/**
 @file sys_tsingma_peri.c

 @date 2018-03-06

 @version v1.0

 The file define APIs of chip of sys layer
*/
/****************************************************************************
 *
 * Header Files
 *
 ****************************************************************************/
#include "ctc_error.h"
#include "ctc_register.h"
#include "ctc_warmboot.h"
#include "sys_usw_peri.h"
#include "sys_usw_chip_global.h"
#include "sys_usw_mac.h"
#include "sys_usw_dmps.h"
#include "sys_usw_chip.h"
#include "sys_usw_datapath.h"
#include "sys_usw_common.h"
#include "sys_usw_interrupt.h"
#include "sys_tsingma_peri.h"
#include "drv_api.h"
#include "sys_usw_eunit.h"
#include "sys_usw_phy.h"
/****************************************************************************
 *
* Defines and Macros
*
*****************************************************************************/

/****************************************************************************
 *
 * Global and static
 *
 *****************************************************************************/
#define SYS_TSINGMA_MDIO_CTLR_NUM MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM)
#define SYS_TSINGMA_TEMP_TABLE_NUM 166
#define SYS_TSINGMA_SENSOR_TIMEOUT 1000
#define SYS_TSINGMA_ZERO_TEMP_INDEX 40 /*0 temp, in temp array index*/
#define SYS_TM_MDIO_INTERFACE_NUM 2   /*interface number per MDIO control*/
#define SYS_TSINGMA_MAX_PHY_NUM_PER_BUS 32
#define SYS_TSINGMA_PHY_BMP_CNT  6
#define SYS_TSINGMA_LED_NUMBER_PER_TABLE 4

#define SYS_TEMP_TABLE_NUM 166


extern sys_peri_master_t* p_usw_peri_master[CTC_MAX_LOCAL_CHIP_NUM_PP];

/****************************************************************************
 *
 * Function
 *
 *****************************************************************************/
#define __MDIO_INTERFACE__

STATIC int32
_sys_tsingma_peri_get_mdio_tbl(uint8 lchip, uint32 tbl_in, uint8 control_id, uint32* tbl_out, uint8* index)
{

    if (tbl_in == MdioCmd0_t)
    {
        if (SYS_MDIO_CONTROL_ID0 == control_id)
        {
            *tbl_out = MdioCmd0_t;
            *index = 0;
        }
        else if (SYS_MDIO_CONTROL_ID1 == control_id)
        {
            *tbl_out = DRV_FROM_TMM(lchip)?MdioCmd0_t:MdioCmd1_t;
            *index = DRV_FROM_TMM(lchip)?1:0;
        }
        else if (DRV_FROM_TMM(lchip) && (SYS_MDIO_CONTROL_ID2 == control_id))
        {
            *tbl_out = MdioCmd1_t;
            *index = 0;
        }
        else if (DRV_FROM_TMM(lchip) && (SYS_MDIO_CONTROL_ID3 == control_id))
        {
            *tbl_out = MdioCmd1_t;
            *index = 1;
        }
    }
    else if (tbl_in == MdioStatus0_t)
    {
        if (SYS_MDIO_CONTROL_ID0 == control_id)
        {
            *tbl_out = MdioStatus0_t;
            *index = 0;
        }
        else if (SYS_MDIO_CONTROL_ID1 == control_id)
        {
            *tbl_out = DRV_FROM_TMM(lchip)?MdioStatus0_t:MdioStatus1_t;
            *index = DRV_FROM_TMM(lchip)?1:0;
        }
        else if (DRV_FROM_TMM(lchip) && (SYS_MDIO_CONTROL_ID2 == control_id))
        {
            *tbl_out = MdioStatus1_t;
            *index = 0;
        }
        else if (DRV_FROM_TMM(lchip) && (SYS_MDIO_CONTROL_ID3 == control_id))
        {
            *tbl_out = MdioStatus1_t;
            *index = 1;
        }
    }
    else if (tbl_in == MdioScanCtl0_t)
    {
        if (SYS_MDIO_CONTROL_ID0 == control_id)
        {
            *tbl_out = MdioScanCtl0_t;
            *index = 0;
        }
        else if (SYS_MDIO_CONTROL_ID1 == control_id)
        {
            *tbl_out = DRV_FROM_TMM(lchip)?MdioScanCtl0_t:MdioScanCtl1_t;
            *index = DRV_FROM_TMM(lchip)?1:0;
        }
        else if (DRV_FROM_TMM(lchip) && (SYS_MDIO_CONTROL_ID2 == control_id))
        {
            *tbl_out = MdioScanCtl1_t;
            *index = 0;
        }
        else if (DRV_FROM_TMM(lchip) && (SYS_MDIO_CONTROL_ID3 == control_id))
        {
            *tbl_out = MdioScanCtl1_t;
            *index = 1;
        }
    }
    else if (tbl_in == MdioCfg0_t)
    {
        if (SYS_MDIO_CONTROL_ID0 == control_id)
        {
            *tbl_out = MdioCfg0_t;
            *index = 0;
        }
        else if (SYS_MDIO_CONTROL_ID1 == control_id)
        {
            *tbl_out = DRV_FROM_TMM(lchip)?MdioCfg0_t:MdioCfg1_t;
            *index = DRV_FROM_TMM(lchip)?1:0;
        }
        else if ((SYS_MDIO_CONTROL_ID2 == control_id) && DRV_FROM_TMM(lchip))
        {
            *tbl_out = MdioCfg1_t;
            *index = 0;
        }
        else if ((SYS_MDIO_CONTROL_ID3 == control_id) && DRV_FROM_TMM(lchip))
        {
            *tbl_out = MdioCfg1_t;
            *index = 1;
        }
    }

    return CTC_E_NONE;
}

/* called by MDIO scan init and dynamic switch */
int32
sys_tsingma_peri_set_phy_scan_cfg(uint8 lchip)
{
    uint16 lport = 0;
    uint8 gchip = 0;
    uint32 mac_id = 0;
    uint32 use_phy[SYS_CHIP_CONTROL_NUM][SYS_TSINGMA_PHY_BMP_CNT] = {{0}, {0}};
    uint8 mdio_bus  = 0;
    uint32 cmd = 0;
    uint32 arr_phy[SYS_TSINGMA_PHY_BMP_CNT] = {0};
    ctc_chip_phy_mapping_para_t* p_phy_mapping = NULL;
    MdioUserPhy_m        user_phy;
    uint32 port_type  = 0;
    uint32 field_value = 0;
    uint8 phy_addr = 0;
    int32 ret = 0;
    uint32 tbl_id = 0;
    uint32 phy_bitmap0[SYS_CHIP_MAX_MDIO_BUS] = {0};
    uint32 phy_bitmap1[SYS_CHIP_MAX_MDIO_BUS] = {0};
    MdioScanCtl0_m mdio_scan;
    uint8 ctl_id = 0;
    uint8 step = 0;
    uint8 index = 0;
    uint8 tbl_index = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&user_phy , 0, sizeof(MdioUserPhy_m));

    p_phy_mapping = (ctc_chip_phy_mapping_para_t*)mem_malloc(MEM_SYSTEM_MODULE, sizeof(ctc_chip_phy_mapping_para_t));
    if (NULL == p_phy_mapping)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_phy_mapping, 0, sizeof(ctc_chip_phy_mapping_para_t));

    CTC_ERROR_GOTO(sys_usw_phy_get_phy_mapping(lchip, p_phy_mapping), ret, out);
    CTC_ERROR_GOTO(sys_usw_get_gchip_id(lchip, &gchip), ret, out);

    /*2. cfg mdio use phy or not to select link status source */
    for (lport = 0; lport < SYS_PHY_PORT_NUM_PER_SLICE; lport++)
    {
        if (p_phy_mapping->port_phy_mapping_tbl[lport] != 0xff)
        {
            dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);

            CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, &mac_id), ret, out);
            if(DMPS_INVALID_VALUE_U32 == mac_id)
            {
                continue;
            }
            mdio_bus = p_phy_mapping->port_mdio_mapping_tbl[lport];
            CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type), ret, out);
            if ((SYS_DMPS_NETWORK_PORT != port_type) && (SYS_DMPS_CPUMAC_NETWORK_PORT != port_type))
            {
                continue;
            }
            /* cpumac */
            if (mac_id >= SYS_CPU_MAC_ID_MIN && mac_id <= SYS_CPU_MAC_ID_MAX)
            {
                tbl_index = (mac_id - SYS_CPU_MAC_ID_MIN) / MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP);
                mac_id = mac_id - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP) - (tbl_index? MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP) : 0);
            }
            else if (mac_id >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP))
            {
                mac_id = mac_id - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP);
                tbl_index = 1;
            }

            field_value = mac_id;
            phy_addr = p_phy_mapping->port_phy_mapping_tbl[lport];
            if (0xFF == phy_addr)
            {
                continue;
            }
            ctl_id = DRV_FROM_AT(lchip) ? (mdio_bus / SYS_CHIP_CONTROL_NUM) % SYS_PERI_MDIO_CTRL_NUM_PER_CORE:\
                                          (mdio_bus / SYS_CHIP_CONTROL_NUM);
            SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, (mdio_bus / SYS_CHIP_CONTROL_NUM));
            mdio_bus = mdio_bus % SYS_CHIP_CONTROL_NUM;
            if (DRV_FROM_TMM(lchip))
            {
                if (0 == ctl_id || 2 == ctl_id)
                {
                    tbl_id = MdioPortIdMap0_t;
                }
                else
                {
                    tbl_id = MdioPortIdMap1_t;
                }
            }
            else
            {
                step = MdioPortIdMap1_t - MdioPortIdMap0_t;
                tbl_id = MdioPortIdMap0_t + ctl_id * step;
            }
            cmd = DRV_IOW(tbl_id, MdioPortIdMap0_macId_f);
            /*
            DP 0 bus 0/1 and 4/5
            DP 1 bus 2/3 and 6/7
            */
            phy_addr = phy_addr + (mdio_bus + (ctl_id >= 2? 2: 0)) * SYS_TSINGMA_MAX_PHY_NUM_PER_BUS;
            DRV_FIELD_IOCTL(lchip, phy_addr, DRV_CMD_PP_EN(cmd), &field_value);

            if (DRV_FROM_TMM(lchip))
            {
                use_phy[tbl_index][mac_id / SYS_TSINGMA_MAX_PHY_NUM_PER_BUS] |= (1 << (mac_id - (mac_id / SYS_TSINGMA_MAX_PHY_NUM_PER_BUS) * SYS_TSINGMA_MAX_PHY_NUM_PER_BUS));

                if (phy_addr < SYS_TSINGMA_MAX_PHY_NUM_PER_BUS)
                {
                    phy_bitmap0[ctl_id] |= (1 << phy_addr);
                }
                else if (phy_addr < 64)
                {
                    phy_bitmap1[ctl_id] |= (1 << (phy_addr - SYS_TSINGMA_MAX_PHY_NUM_PER_BUS));
                }
                else if (phy_addr < 96)
                {
                    phy_bitmap0[ctl_id] |= (1 << (phy_addr - 64));
                }
                else
                {
                    phy_bitmap1[ctl_id] |= (1 << (phy_addr - 96));
                }
            }
            else
            {
                if (mac_id < SYS_TSINGMA_MAX_PHY_NUM_PER_BUS)
                {
                    use_phy[0][0]  |= (1 << mac_id);
                }
                else
                {
                    use_phy[0][1]  |= (1 << (mac_id - SYS_TSINGMA_MAX_PHY_NUM_PER_BUS));
                }
                if (phy_addr < SYS_TSINGMA_MAX_PHY_NUM_PER_BUS)
                {
                    phy_bitmap0[ctl_id] |= (1 << phy_addr);
                }
                else
                {
                    phy_bitmap1[ctl_id] |= (1 << (phy_addr - SYS_TSINGMA_MAX_PHY_NUM_PER_BUS));
                }
            }
        }
    }

    if (DRV_FROM_TMM(lchip))
    {
        /* config use phy or not */
        for (index = 0 ; index < SYS_CHIP_CONTROL_NUM; index++)
        {
            ctl_id = DRV_FROM_AT(lchip) ? index % SYS_PERI_MDIO_CTRL_NUM_PER_CORE:index;
            SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, index);
            sal_memcpy(arr_phy, use_phy[index], sizeof(arr_phy));
            cmd = DRV_IOR(MdioUserPhy_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &user_phy);
            SetMdioUserPhy(A, usePhy_f, &user_phy, arr_phy);
            cmd = DRV_IOW(MdioUserPhy_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &user_phy);
        }
    }
    else
    {
        /* config use phy or not */
        arr_phy[0] = use_phy[0][0];
        arr_phy[1] = use_phy[0][1];
        cmd = DRV_IOR(MdioUserPhy_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &user_phy);
        SetMdioUserPhy(A, usePhy_f, &user_phy, arr_phy);
        cmd = DRV_IOW(MdioUserPhy_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &user_phy);
    }

    for (index = 0; index < SYS_PERI_MDIO_CTRL_NUM_PER_CORE; index++)
    {
        CTC_ERROR_GOTO(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioScanCtl0_t, index, &tbl_id, &tbl_index), ret, out);
        /* config mdio phy bitmap */
        sal_memset(&mdio_scan, 0, sizeof(MdioScanCtl0_m));
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, tbl_index, cmd, &mdio_scan);
        DRV_IOW_FIELD(lchip, tbl_id, MdioScanCtl0_mdioScanBmp0Lane0_f,
                &phy_bitmap0[index], &mdio_scan);
        DRV_IOW_FIELD(lchip, tbl_id, MdioScanCtl0_mdioScanBmp1Lane0_f,
                &phy_bitmap1[index], &mdio_scan);
        SetMdioScanCtl0(V, linkStatusIntrEnLane0_f, &mdio_scan, 1);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, tbl_index, cmd, &mdio_scan);
    }

out:
    if (p_phy_mapping)
    {
        mem_free(p_phy_mapping);
    }

    return ret;
}

STATIC int32
_sys_tsingma_peri_set_mdio_phy_type(uint8 lchip, uint8 ctlr_id, uint32 type)
{
    uint32 cmd = 0;
    uint32 mdio_phy_type = 0;
    uint32 tbl_id = 0;
    uint8  tbl_idx = 0;

    CTC_ERROR_RETURN(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioCfg0_t, ctlr_id, &tbl_id, &tbl_idx));
    cmd = DRV_IOR(tbl_id, MdioCfg0_mdioIsXgModeLane0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_phy_type));

    if (mdio_phy_type != type)
    {
        cmd = DRV_IOW(tbl_id, MdioCfg0_mdioIsXgModeLane0_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &type));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_peri_get_mdio_phy_type(uint8 lchip, uint8 ctlr_id, uint32* type)
{
    uint32 cmd = 0;
    uint32 mdio_phy_type = 0;
    uint32 tbl_id = 0;
    uint8  tbl_idx = 0;

    CTC_ERROR_RETURN(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioCfg0_t, ctlr_id, &tbl_id, &tbl_idx));
    cmd = DRV_IOR(tbl_id, MdioCfg0_mdioIsXgModeLane0_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_phy_type));

    *type = mdio_phy_type;

    return CTC_E_NONE;
}

/**
 @brief set phy samping offset crycle
*/
int32
sys_tsingma_peri_set_phy_sample_offset(uint8 lchip, ctc_chip_mdio_para_t* p_mdio_para)
{
    uint32 cmd = 0;
    uint32 tbl_id = 0;
    uint8 tbl_idx = 0;
    uint8 mdio_ctlr_id = 0;
    uint32 field_value = 0;
    MdioCfg0_m  mdio_cfg;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mdio_para);
    CTC_MAX_VALUE_CHECK(p_mdio_para->bus, (SYS_CHIP_CONTROL_NUM * MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set phy sample offset: bus %d value %d\n", p_mdio_para->bus, p_mdio_para->value);

    if (CTC_IS_BIT_SET(p_mdio_para->value, SYS_PERI_PHY_SAMPLE_OFFSET_MAX))
    {
        CTC_BIT_UNSET(p_mdio_para->value, SYS_PERI_PHY_SAMPLE_OFFSET_MAX);
        CTC_MAX_VALUE_CHECK(p_mdio_para->value, SYS_PERI_PHY_SAMPLE_OFFSET_DEFAULT);
        field_value = SYS_PERI_PHY_SAMPLE_OFFSET_DEFAULT - p_mdio_para->value;
    }
    else
    {
        CTC_MAX_VALUE_CHECK(p_mdio_para->value, SYS_PERI_PHY_SAMPLE_OFFSET_MAX -
            SYS_PERI_PHY_SAMPLE_OFFSET_DEFAULT);
        field_value = SYS_PERI_PHY_SAMPLE_OFFSET_DEFAULT + p_mdio_para->value;
    }
    mdio_ctlr_id = p_mdio_para->bus / SYS_CHIP_BUS_NUM_PER_CTL;
    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, mdio_ctlr_id);
    mdio_ctlr_id = DRV_FROM_AT(lchip)?mdio_ctlr_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE:mdio_ctlr_id;
    CTC_ERROR_RETURN(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioCfg0_t, mdio_ctlr_id, &tbl_id, &tbl_idx));

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_cfg));
    SetMdioCfg0(V, mdioInDlyLane0_f, &mdio_cfg, field_value);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_cfg));

    return CTC_E_NONE;
}

/**
 @brief get phy samping offset crycle
*/
int32
sys_tsingma_peri_get_phy_sample_offset(uint8 lchip, ctc_chip_mdio_para_t* p_mdio_para)
{
    uint32 cmd = 0;
    uint32 tbl_id = 0;
    uint8 tbl_idx = 0;
    uint8 mdio_ctlr_id = 0;
    uint32 field_value = 0;
    MdioCfg0_m mdio_cfg;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mdio_para);
    CTC_MAX_VALUE_CHECK(p_mdio_para->bus, (SYS_CHIP_CONTROL_NUM * MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    mdio_ctlr_id = p_mdio_para->bus / SYS_CHIP_BUS_NUM_PER_CTL;
    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, mdio_ctlr_id);
    mdio_ctlr_id = DRV_FROM_AT(lchip)?mdio_ctlr_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE:mdio_ctlr_id;
    CTC_ERROR_RETURN(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioCfg0_t, mdio_ctlr_id, &tbl_id, &tbl_idx));

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_cfg));
    field_value = GetMdioCfg0(V, mdioInDlyLane0_f, &mdio_cfg);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get phy sample offset: bus %d value %d\n", p_mdio_para->bus, field_value);
    p_mdio_para->value = (field_value >=SYS_PERI_PHY_SAMPLE_OFFSET_DEFAULT)?
        (field_value - SYS_PERI_PHY_SAMPLE_OFFSET_DEFAULT): (SYS_PERI_PHY_SAMPLE_OFFSET_DEFAULT - field_value)|(1<<SYS_PERI_PHY_SAMPLE_OFFSET_MAX);

    return CTC_E_NONE;
}

/**
 @brief set phy sample edge mode
*/
int32
sys_tsingma_peri_set_phy_sample_edge(uint8 lchip, ctc_chip_mdio_para_t* p_mdio_para)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 mdio_ctlr_id = 0;
    uint8 mdio_bus = 0;
    uint32 field_id = 0;
    MdioMacroClkPhaseSel_m mdio_clk_sel;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mdio_para);
    CTC_MAX_VALUE_CHECK(p_mdio_para->bus, (SYS_CHIP_CONTROL_NUM * MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set phy sample edge mode: bus %d value %d\n", p_mdio_para->bus, p_mdio_para->value);

    field_value = p_mdio_para->value ? 1: 0;
    mdio_ctlr_id = p_mdio_para->bus / SYS_CHIP_BUS_NUM_PER_CTL;
    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, mdio_ctlr_id);

    cmd = DRV_IOR(MdioMacroClkPhaseSel_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mdio_clk_sel);
    mdio_bus = DRV_FROM_AT(lchip) ? p_mdio_para->bus % SYS_PERI_MDIO_BUS_NUM_PER_CORE:(DRV_FROM_TMM(lchip) ? p_mdio_para->bus:(p_mdio_para->bus % SYS_CHIP_BUS_NUM_PER_CTL));

    if (DRV_IS_TSINGMA(lchip))
    {
        field_id = MdioMacroClkPhaseSel_cfgSelectMdioA0Inv_f + mdio_bus*(MdioMacroClkPhaseSel_cfgSelectMdioA1Inv_f - MdioMacroClkPhaseSel_cfgSelectMdioA0Inv_f) 
                     + mdio_ctlr_id *(MdioMacroClkPhaseSel_cfgSelectMdioB0Inv_f - MdioMacroClkPhaseSel_cfgSelectMdioA0Inv_f);
        DRV_SET_FIELD_V(lchip, MdioMacroClkPhaseSel_t, field_id, &mdio_clk_sel, field_value);

    }
    else if(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))
    {
        SetMdioMacroClkPhaseSel(V, cfgSelectDp0MdioA0Inv_f + mdio_bus, &mdio_clk_sel, field_value);
    }
    else if(DRV_FROM_AT(lchip))
    {
        SetMdioMacroClkPhaseSel(V, cfgSelectMdioA0Inv_f + mdio_bus, &mdio_clk_sel, field_value);
    }
    cmd = DRV_IOW(MdioMacroClkPhaseSel_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mdio_clk_sel));

    return CTC_E_NONE;
}

/**
 @brief get phy sampe edge mode
*/
int32
sys_tsingma_peri_get_phy_sample_edge(uint8 lchip, ctc_chip_mdio_para_t* p_mdio_para)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint8 mdio_ctlr_id = 0;
    uint8 mdio_bus = 0;
    uint32 field_id = 0;
    MdioMacroClkPhaseSel_m mdio_clk_sel;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_mdio_para);
    CTC_MAX_VALUE_CHECK(p_mdio_para->bus, (SYS_CHIP_CONTROL_NUM * MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    mdio_ctlr_id = p_mdio_para->bus / SYS_CHIP_BUS_NUM_PER_CTL;
    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, mdio_ctlr_id);
    mdio_bus = DRV_FROM_AT(lchip) ? p_mdio_para->bus % SYS_PERI_MDIO_BUS_NUM_PER_CORE:(DRV_FROM_TMM(lchip) ? p_mdio_para->bus:(p_mdio_para->bus % SYS_CHIP_BUS_NUM_PER_CTL));
    cmd = DRV_IOR(MdioMacroClkPhaseSel_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mdio_clk_sel);
    if (DRV_IS_TSINGMA(lchip))
    {
        field_id = MdioMacroClkPhaseSel_cfgSelectMdioA0Inv_f + mdio_bus*(MdioMacroClkPhaseSel_cfgSelectMdioA1Inv_f - MdioMacroClkPhaseSel_cfgSelectMdioA0Inv_f) 
                     + mdio_ctlr_id *(MdioMacroClkPhaseSel_cfgSelectMdioB0Inv_f - MdioMacroClkPhaseSel_cfgSelectMdioA0Inv_f);
        field_value = DRV_GET_FIELD_V(lchip, MdioMacroClkPhaseSel_t, field_id, &mdio_clk_sel);
    }
    else if (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))
    {
        field_value = GetMdioMacroClkPhaseSel(V, cfgSelectDp0MdioA0Inv_f + mdio_bus, &mdio_clk_sel);
    }
    else if (DRV_FROM_AT(lchip))
    {
        field_value = GetMdioMacroClkPhaseSel(V, cfgSelectMdioA0Inv_f + mdio_bus, &mdio_clk_sel);
    }

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get phy sample edge mode: bus %d value %d\n", p_mdio_para->bus, field_value);
    p_mdio_para->value = field_value;

    return CTC_E_NONE;
}

/**
 @brief smi interface for set auto scan para
*/
int32
sys_tsingma_peri_set_phy_scan_para(uint8 lchip, ctc_chip_phy_scan_ctrl_t* p_scan_para)
{
    uint32 cmd = 0;
    MdioScanCtl0_m  scan_ctrl;
    uint32 tmp_val32 = 0;
    uint8 mdio_ctlr_id = 0;
    uint32 tbl_id = 0;
    int32  ret = 0;
    uint8  tbl_idx = 0;

    CTC_PTR_VALID_CHECK(p_scan_para);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "Set Scan Para op_flag:0x%x interval:0x%x   \
        bitmask:0x%x scan_twice:%d mdio_ctlr_id:%d mdio_ctlr_type:%d phybitmap0:0x%x phybitmap1:0x%x\n",
                     p_scan_para->op_flag, p_scan_para->scan_interval,
                     p_scan_para->xgphy_link_bitmask, p_scan_para->xgphy_scan_twice,
                     p_scan_para->mdio_ctlr_id, p_scan_para->mdio_ctlr_type, p_scan_para->scan_phy_bitmap0, p_scan_para->scan_phy_bitmap1);

    if((SYS_TSINGMA_MDIO_CTLR_NUM <= p_scan_para->mdio_ctlr_id) ||
       (1 < p_scan_para->mdio_ctlr_type) ||
       (0xffff < p_scan_para->scan_interval) ||
       (0x7 < p_scan_para->xgphy_link_bitmask) ||
       (0x1 < p_scan_para->xgphy_scan_twice))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_tsingma_peri_set_phy_scan_para: out of bound! %d %d %d %d %d\n",
                         p_scan_para->mdio_ctlr_id, p_scan_para->mdio_ctlr_type, p_scan_para->scan_interval,
                         p_scan_para->xgphy_link_bitmask, p_scan_para->xgphy_scan_twice);
        return CTC_E_INVALID_PARAM;
    }

    if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_USE_PHY_OP))
    {
        return CTC_E_NOT_SUPPORT;
    }

    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, p_scan_para->mdio_ctlr_id);
    SYS_PERI_SMI_LOCK(lchip);
    mdio_ctlr_id = DRV_FROM_AT(lchip) ? p_scan_para->mdio_ctlr_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE : p_scan_para->mdio_ctlr_id;
    /* config type of phy, GE PHY or XG PHY */
    CTC_ERROR_GOTO(_sys_tsingma_peri_set_mdio_phy_type(lchip, mdio_ctlr_id, p_scan_para->mdio_ctlr_type), ret, error_proc);
    CTC_ERROR_GOTO(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioScanCtl0_t, mdio_ctlr_id, &tbl_id, &tbl_idx), ret, error_proc);

    /* config scan parameters, MdioScanCtl  */
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &scan_ctrl), ret, error_proc);

    /* config scan interval */
    if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_INTERVAL_OP)
        || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag))
    {
        tmp_val32 = p_scan_para->scan_interval;
        DRV_IOW_FIELD(lchip, tbl_id, MdioScanCtl0_scanIntervalLane0_f,
            &tmp_val32, &scan_ctrl);
    }
    /* config scan phy bitmap */
    if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_PHY_BITMAP_OP)
        || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag) )
    {
        tmp_val32 = p_scan_para->scan_phy_bitmap0;
        DRV_IOW_FIELD(lchip, tbl_id, MdioScanCtl0_mdioScanBmp0Lane0_f,
            &tmp_val32, &scan_ctrl);
        tmp_val32 = p_scan_para->scan_phy_bitmap1;
        DRV_IOW_FIELD(lchip, tbl_id, MdioScanCtl0_mdioScanBmp1Lane0_f,
            &tmp_val32, &scan_ctrl);
    }
    /* for XG phy only */
    if (CTC_CHIP_MDIO_XG == p_scan_para->mdio_ctlr_type)
    {
        if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_XG_LINK_MASK_OP)
            || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag))
        {
            tmp_val32 = p_scan_para->xgphy_link_bitmask;
            DRV_IOW_FIELD(lchip, tbl_id, MdioScanCtl0_xgLinkBmpMaskLane0_f,
                &tmp_val32, &scan_ctrl);
        }

        if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_XG_TWICE_OP)
            || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag))
        {
            tmp_val32 = p_scan_para->xgphy_scan_twice;
            DRV_IOW_FIELD(lchip, tbl_id, MdioScanCtl0_scanXGTwiceLane0_f,
                &tmp_val32, &scan_ctrl);
        }
    }
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &scan_ctrl), ret, error_proc);

error_proc:
    SYS_PERI_SMI_UNLOCK(lchip);

    return ret;
}

int32
sys_tsingma_peri_get_phy_scan_para(uint8 lchip, ctc_chip_phy_scan_ctrl_t* p_scan_para)
{
    uint32 cmd = 0;
    MdioScanCtl0_m  scan_ctrl;
    uint32 tmp_val32 = 0;
    uint8 mdio_ctlr_id = 0;
    uint32 tbl_id = 0;
    uint32 type = 0;
    uint8  tbl_idx = 0;
    int32  ret = 0;

    CTC_PTR_VALID_CHECK(p_scan_para);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_PARAM, "Get Scan Para op_flag:0x%x mdio_ctlr_id:%d\n",
                     p_scan_para->op_flag, p_scan_para->mdio_ctlr_id);

    if(SYS_TSINGMA_MDIO_CTLR_NUM <= p_scan_para->mdio_ctlr_id)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_tsingma_peri_get_phy_scan_para: out of bound! %d\n",
                         p_scan_para->mdio_ctlr_id);
        return CTC_E_INVALID_PARAM;
    }

    sal_memset(&scan_ctrl, 0, sizeof(MdioScanCtl0_m));

    SYS_PERI_SMI_LOCK(lchip);

    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, mdio_ctlr_id);
    mdio_ctlr_id = DRV_FROM_AT(lchip) ? p_scan_para->mdio_ctlr_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE : p_scan_para->mdio_ctlr_id;
    _sys_tsingma_peri_get_mdio_phy_type(lchip, mdio_ctlr_id, &type);
    p_scan_para->mdio_ctlr_type = type;

    CTC_ERROR_GOTO(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioScanCtl0_t, mdio_ctlr_id, &tbl_id, &tbl_idx), ret, error_proc);
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &scan_ctrl), ret, error_proc);

    /* config scan interval */
    if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_INTERVAL_OP)
        || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag))
    {
        DRV_IOR_FIELD(lchip, tbl_id, MdioScanCtl0_scanIntervalLane0_f,
            &tmp_val32, &scan_ctrl);
        p_scan_para->scan_interval = tmp_val32;
    }
    /* config scan phy bitmap */
    if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_PHY_BITMAP_OP)
        || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag) )
    {
        DRV_IOR_FIELD(lchip, tbl_id, MdioScanCtl0_mdioScanBmp0Lane0_f,
            &tmp_val32, &scan_ctrl);
        p_scan_para->scan_phy_bitmap0 = tmp_val32;

        DRV_IOR_FIELD(lchip, tbl_id, MdioScanCtl0_mdioScanBmp1Lane0_f,
            &tmp_val32, &scan_ctrl);
        p_scan_para->scan_phy_bitmap1 = tmp_val32;
    }
    /* for XG phy only */
    if (CTC_CHIP_MDIO_XG == p_scan_para->mdio_ctlr_type)
    {
        if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_XG_LINK_MASK_OP)
            || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag))
        {
            DRV_IOR_FIELD(lchip, tbl_id, MdioScanCtl0_xgLinkBmpMaskLane0_f,
                &tmp_val32, &scan_ctrl);
            p_scan_para->xgphy_link_bitmask = tmp_val32;
        }

        if (SYS_CHIP_FLAG_ISSET(p_scan_para->op_flag, CTC_CHIP_XG_TWICE_OP)
            || SYS_CHIP_FLAG_ISZERO(p_scan_para->op_flag))
        {
            DRV_IOR_FIELD(lchip, tbl_id, MdioScanCtl0_scanXGTwiceLane0_f,
                &tmp_val32, &scan_ctrl);
            p_scan_para->xgphy_scan_twice = tmp_val32;
        }
    }

error_proc:
    SYS_PERI_SMI_UNLOCK(lchip);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get Scan Para op_flag:0x%x interval:0x%x bitmask:0x%x scan_twice:%d \
        mdio_ctlr_id:%d mdio_ctlr_type:%d phybitmap0:0x%x phybitmap1:0x%x usephy0: 0x%x usephy1: 0x%x\n",
                     p_scan_para->op_flag, p_scan_para->scan_interval, p_scan_para->xgphy_link_bitmask, \
                     p_scan_para->xgphy_scan_twice, p_scan_para->mdio_ctlr_id, p_scan_para->mdio_ctlr_type, \
                     p_scan_para->scan_phy_bitmap0, p_scan_para->scan_phy_bitmap1, p_scan_para->mdio_use_phy0, p_scan_para->mdio_use_phy1);

    return CTC_E_NONE;
}
/**
 @brief mdio interface for read ge phy
*/
int32
sys_tsingma_peri_read_phy_reg(uint8 lchip, ctc_chip_mdio_type_t type, ctc_chip_mdio_para_t* p_para)
{
    MdioCmd0_m mdio_cmd;
    MdioStatus0_m mdio_status;
    uint8 mdio1_g_cmd_done = 0;
    uint32 timeout = SYS_CHIP_MAX_TIME_OUT;
    uint32 cmd = 0;
    uint8 mdio_ctlr_id = 0;
    uint32 mdio_intf_id = 0;
    int32 ret = 0;
    uint32 tbl_id = 0;
    uint8 tbl_idx = 0;

    /* Duet2 support access XG PHY by GE PHY interface, other chips not support */
    if (CTC_CHIP_MDIO_XGREG_BY_GE == type)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_tsingma_peri_read_phy_reg: type (%d) invalid!\n", type);
        return CTC_E_INVALID_PARAM;
    }

    sal_memset(&mdio_cmd, 0, sizeof(MdioCmd0_m));
    sal_memset(&mdio_status, 0, sizeof(MdioStatus0_m));

    mdio_ctlr_id = p_para->bus / SYS_TM_MDIO_INTERFACE_NUM;
    mdio_intf_id = p_para->bus % SYS_TM_MDIO_INTERFACE_NUM;

    if (SYS_TSINGMA_MDIO_CTLR_NUM <= mdio_ctlr_id)
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, mdio_ctlr_id);
    mdio_ctlr_id = DRV_FROM_AT(lchip) ? mdio_ctlr_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE : mdio_ctlr_id;
    CTC_ERROR_RETURN(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioCmd0_t, mdio_ctlr_id, &tbl_id, &tbl_idx));

    SYS_PERI_SMI_LOCK(lchip);
    CTC_ERROR_GOTO(_sys_tsingma_peri_set_mdio_phy_type(lchip, mdio_ctlr_id, type), ret, error_proc);

    /* #2, write ctl_id/bus/address */
    /* mdiocmd  */
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_cmd), ret, error_proc);

    if (CTC_CHIP_MDIO_GE == type)
    {
        SetMdioCmd0(V, opCodeCmdLane0_f, &mdio_cmd, SYS_CHIP_1G_MDIO_READ);
        SetMdioCmd0(V, startCmdLane0_f, &mdio_cmd, 0x1);
        SetMdioCmd0(V, regAddCmdLane0_f, &mdio_cmd, p_para->dev_no);
        SetMdioCmd0(V, devAddCmdLane0_f, &mdio_cmd, p_para->reg);
    }
    else if (CTC_CHIP_MDIO_XG == type)
    {
        SetMdioCmd0(V, opCodeCmdLane0_f, &mdio_cmd, SYS_CHIP_XG_MDIO_READ);
        SetMdioCmd0(V, startCmdLane0_f, &mdio_cmd, 0x0);
        SetMdioCmd0(V, regAddCmdLane0_f, &mdio_cmd, p_para->reg);
        SetMdioCmd0(V, devAddCmdLane0_f, &mdio_cmd, p_para->dev_no);
    }
    SetMdioCmd0(V, intfSelCmdLane0_f, &mdio_cmd, mdio_intf_id);
    SetMdioCmd0(V, portAddCmdLane0_f, &mdio_cmd, p_para->phy_addr);

    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_cmd), ret, error_proc);

    /* #3, check status done */
    /*mdiostatus*/
    CTC_ERROR_GOTO(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioStatus0_t, mdio_ctlr_id, &tbl_id, &tbl_idx), ret, error_proc);

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_status), ret, error_proc);

    mdio1_g_cmd_done = GetMdioStatus0(V, mdioCmdDoneLane0_f, &mdio_status);
    while ((mdio1_g_cmd_done == 0) && (timeout--))
    {
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_status), ret, error_proc);
        mdio1_g_cmd_done = GetMdioStatus0(V, mdioCmdDoneLane0_f, &mdio_status);
    }

    if (mdio1_g_cmd_done == 0)
    {
        ret = CTC_E_INVALID_CONFIG;
        goto error_proc;
    }

    /* #4, read data */
    p_para->value = GetMdioStatus0(V, mdioReadDataLane0_f, &mdio_status);

error_proc:
    SYS_PERI_SMI_UNLOCK(lchip);
    return ret;
}

/**
 @brief mdio interface for write ge phy
*/
int32
sys_tsingma_peri_write_phy_reg(uint8 lchip, ctc_chip_mdio_type_t type, ctc_chip_mdio_para_t* p_para)
{
    MdioCmd0_m mdio_cmd;
    MdioStatus0_m mdio_status;
    uint8 mdio1_g_cmd_done = 0;
    uint32 timeout = SYS_CHIP_MAX_TIME_OUT;
    uint32 cmd = 0;
    uint8 mdio_ctlr_id = 0;
    uint32 mdio_intf_id = 0;
    int32 ret = 0;
    uint32 tbl_id = 0;
    uint8 tbl_idx = 0;

    /* Duet2 support access XG PHY by GE PHY interface, other chips not support */
    if (CTC_CHIP_MDIO_XGREG_BY_GE == type)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_tsingma_peri_read_phy_reg: type (%d) invalid!\n", type);
        return CTC_E_INVALID_PARAM;
    }
    sal_memset(&mdio_cmd, 0, sizeof(MdioCmd0_m));
    sal_memset(&mdio_status, 0, sizeof(MdioStatus0_m));

    mdio_ctlr_id = p_para->bus / SYS_TM_MDIO_INTERFACE_NUM;
    mdio_intf_id = p_para->bus % SYS_TM_MDIO_INTERFACE_NUM;
    if (SYS_TSINGMA_MDIO_CTLR_NUM <= mdio_ctlr_id)
    {
        return CTC_E_INVALID_PARAM;
    }

    SYS_PERI_MDIO_MAP_LCHIP_BY_CTRL_ID(lchip, mdio_ctlr_id);
    mdio_ctlr_id = DRV_FROM_AT(lchip) ? mdio_ctlr_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE : mdio_ctlr_id;
    CTC_ERROR_RETURN(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioCmd0_t, mdio_ctlr_id, &tbl_id, &tbl_idx));

    SYS_PERI_SMI_LOCK(lchip);
    CTC_ERROR_GOTO(_sys_tsingma_peri_set_mdio_phy_type(lchip, mdio_ctlr_id, type), ret, error_proc);

    /* #2, write ctl_id/bus/address */
    /* mdiocmd  */
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_cmd), ret, error_proc);

    if (CTC_CHIP_MDIO_GE == type)
    {
        SetMdioCmd0(V, startCmdLane0_f, &mdio_cmd, 0x1);
        SetMdioCmd0(V, regAddCmdLane0_f, &mdio_cmd, p_para->dev_no);
        SetMdioCmd0(V, devAddCmdLane0_f, &mdio_cmd, p_para->reg);
    }
    else if (CTC_CHIP_MDIO_XG == type)
    {
        SetMdioCmd0(V, startCmdLane0_f, &mdio_cmd, 0x0);
        SetMdioCmd0(V, regAddCmdLane0_f, &mdio_cmd, p_para->reg);
        SetMdioCmd0(V, devAddCmdLane0_f, &mdio_cmd, p_para->dev_no);
    }

    SetMdioCmd0(V, intfSelCmdLane0_f, &mdio_cmd, mdio_intf_id);
    SetMdioCmd0(V, opCodeCmdLane0_f, &mdio_cmd, SYS_CHIP_MDIO_WRITE);
    SetMdioCmd0(V, portAddCmdLane0_f, &mdio_cmd, p_para->phy_addr);
    SetMdioCmd0(V, dataCmdLane0_f, &mdio_cmd, p_para->value);

    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_cmd), ret, error_proc);

    /* #3, check status done */
    /*mdiostatus*/
    CTC_ERROR_GOTO(_sys_tsingma_peri_get_mdio_tbl(lchip, MdioStatus0_t, mdio_ctlr_id, &tbl_id, &tbl_idx), ret, error_proc);
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_status), ret, error_proc);

    mdio1_g_cmd_done = GetMdioStatus0(V, mdioCmdDoneLane0_f, &mdio_status);
    while ((mdio1_g_cmd_done == 0) && (--timeout))
    {
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &mdio_status), ret, error_proc);
        mdio1_g_cmd_done = GetMdioStatus0(V, mdioCmdDoneLane0_f, &mdio_status);
    }

    if (mdio1_g_cmd_done == 0)
    {
        ret = CTC_E_INVALID_CONFIG;
        goto error_proc;
    }

error_proc:
    SYS_PERI_SMI_UNLOCK(lchip);
    return ret;
}

/**
 @brief mdio interface to set mdio clock frequency
*/
int32
sys_tsingma_peri_set_mdio_clock(uint8 lchip, ctc_chip_mdio_type_t type, uint16 freq)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint32 core_freq = 0;
    uint8 control_id = 0;
    uint32 ctl_type = 0;
    uint32 div_val = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_MIN_VALUE_CHECK(freq, 1);
    CTC_MAX_VALUE_CHECK(freq, 60000);

    core_freq =  DRV_IS_AT(lchip) ? sys_usw_get_core_freq(lchip, 1) : sys_usw_get_core_freq(lchip, 0);
    div_val = (core_freq*1000)/freq;
    if(0xfff < div_val)
    {
        return CTC_E_INVALID_PARAM;
    }

    for (control_id = 0; control_id < SYS_TSINGMA_MDIO_CTLR_NUM; control_id++)
    {
        _sys_tsingma_peri_get_mdio_phy_type(lchip, control_id, &ctl_type);
        if (type != ctl_type)
        {
            continue;
        }
        if (control_id == 0)
        {
            field_value = div_val;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgClkMdioADiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            field_value = 1;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioADiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            field_value = 0;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioADiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        }
        else if (((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && 2 == control_id) || (DRV_IS_TSINGMA(lchip) && 1 == control_id))
        {
            field_value = div_val;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgClkMdioBDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

            field_value = 1;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioBDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            field_value = 0;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioBDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        }
        else if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && 1 == control_id)
        {
            field_value = div_val;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgClkMdioCDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

            field_value = 1;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioCDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            field_value = 0;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioCDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        }
        else
        {
            field_value = div_val;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgClkMdioDDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

            field_value = 1;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioDDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
            field_value = 0;
            cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkMdioDDiv_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
        }
    }
    return CTC_E_NONE;
}

/**
 @brief mdio interface to get mdio clock frequency
*/
int32
sys_tsingma_peri_get_mdio_clock(uint8 lchip, ctc_chip_mdio_type_t type, uint16* freq)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 core_freq = 0;
    uint8 control_id = 0;
    uint32 ctl_type = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(SDK_WORK_PLATFORM == 0)
    {
        core_freq =  DRV_IS_AT(lchip) ? sys_usw_get_core_freq(lchip, 1) : sys_usw_get_core_freq(lchip, 0);
        for (control_id = 0; control_id < SYS_TSINGMA_MDIO_CTLR_NUM; control_id++)
        {
            _sys_tsingma_peri_get_mdio_phy_type(lchip, control_id, &ctl_type);
            if (type == ctl_type)
            {
                control_id = (((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && 1 == control_id)? 2: (((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && 2 == control_id)? 1: control_id));
                cmd = DRV_IOR(SupDskCfg_t, (SupDskCfg_cfgClkMdioADiv_f+control_id));
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
                break;
            }
        }
        *freq = core_freq*1000/(field_val ? field_val : 1);
    }

    return CTC_E_NONE;
}

#define __MAC_LED_INTERFACE__

/**
 @brief mac led interface to get mac led mode cfg
*/
STATIC int32
_sys_tsingma_peri_get_mac_led_mode_cfg(ctc_chip_led_mode_t mode, uint8* p_value)
{
    uint8 temp = 0;

    switch(mode)
    {
        case CTC_CHIP_RXLINK_MODE:
            temp = (SYS_CHIP_LED_ON_RX_LINK & 0x3)
                | ((SYS_CHIP_LED_BLINK_OFF & 0x3) << 2);
            break;

        case CTC_CHIP_TXLINK_MODE:
            temp = (SYS_CHIP_LED_ON_TX_LINK & 0x3)
                | ((SYS_CHIP_LED_BLINK_OFF & 0x3) << 2);
            break;

        case CTC_CHIP_RXLINK_RXACTIVITY_MODE:
            temp = (SYS_CHIP_LED_ON_RX_LINK & 0x3)
                | ((SYS_CHIP_LED_BLINK_RX_ACT & 0x3) << 2);
            break;

        case CTC_CHIP_TXLINK_TXACTIVITY_MODE:
            temp = (SYS_CHIP_LED_ON_TX_LINK & 0x3)
                | ((SYS_CHIP_LED_BLINK_TX_ACT & 0x3) << 2);
            break;

        case CTC_CHIP_RXLINK_BIACTIVITY_MODE:
            temp = (SYS_CHIP_LED_ON_RX_LINK & 0x3)
                | ((SYS_CHIP_LED_BLINK_ON & 0x3) << 2);
            break;

        case CTC_CHIP_TXACTIVITY_MODE:
            temp = (SYS_CHIP_LED_FORCE_OFF & 0x3)
                | ((SYS_CHIP_LED_BLINK_TX_ACT & 0x3) << 2);
            break;

        case CTC_CHIP_RXACTIVITY_MODE:
            temp = (SYS_CHIP_LED_FORCE_OFF & 0x3)
                | ((SYS_CHIP_LED_BLINK_RX_ACT & 0x3) << 2);
            break;

        case CTC_CHIP_BIACTIVITY_MODE:
            temp = (SYS_CHIP_LED_FORCE_OFF & 0x3)
                | ((SYS_CHIP_LED_BLINK_ON & 0x3) << 2);
            break;

        case CTC_CHIP_FORCE_ON_MODE:
            temp = (SYS_CHIP_LED_FORCE_ON & 0x3)
                | ((SYS_CHIP_LED_BLINK_OFF & 0x3) << 2);
            break;

        case CTC_CHIP_FORCE_OFF_MODE:
            temp = (SYS_CHIP_LED_FORCE_OFF & 0x3)
                | ((SYS_CHIP_LED_BLINK_OFF & 0x3) << 2);
            break;

       case CTC_CHIP_FORCE_ON_TXACTIVITY_MODE:
            temp = (SYS_CHIP_LED_FORCE_ON & 0x3)
                | ((SYS_CHIP_LED_BLINK_TX_ACT & 0x3) << 2);
            break;

       case CTC_CHIP_FORCE_ON_RXACTIVITY_MODE:
            temp = (SYS_CHIP_LED_FORCE_ON & 0x3)
                | ((SYS_CHIP_LED_BLINK_RX_ACT & 0x3) << 2);
            break;

       case CTC_CHIP_FORCE_ON_BIACTIVITY_MODE:
            temp = (SYS_CHIP_LED_FORCE_ON & 0x3)
                | ((SYS_CHIP_LED_BLINK_ON & 0x3) << 2);
            break;

        default:
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_tsingma_peri_get_mac_led_mode_cfg: mode (%d) illegal!\n", mode);
            return CTC_E_INVALID_PARAM;
    }

    *p_value = temp;

    return CTC_E_NONE;
}


/**
 @brief mac led interface
*/
int32
sys_tsingma_peri_set_mac_led_mode(uint8 lchip, ctc_chip_led_para_t* p_led_para, ctc_chip_mac_led_type_t led_type, uint8 inner)
{
    uint32 cmd = 0;
    uint32 field_index = 0;
    LedCfgPortMode_m led_mode;
    LedPolarityCfg_m led_polarity;
    uint8 led_cfg = 0;
    uint16 lport;
    uint32 port_type = 0;
    uint8 is_remote_core = 0;
    uint8 tmp_lchip = 0;
    uint8 gchip_id = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    uint16 break_led_id[] = {0,1,2,3,164,165,166,167};

    CTC_PTR_VALID_CHECK(p_led_para);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&led_mode, 0, sizeof(LedCfgPortMode_m));
    sal_memset(&led_polarity, 0, sizeof(LedPolarityCfg_m));

    CTC_PTR_VALID_CHECK(p_led_para);

    if (led_type >= CTC_CHIP_MAX_LED_TYPE)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_tsingma_peri_set_mac_led_mode: led_type (%d) illegal!\n", led_type);
        return CTC_E_INVALID_PARAM;
    }

    if ((0 != p_led_para->ctl_id && DRV_IS_TSINGMA(lchip)) || ((p_led_para->ctl_id > 1) && DRV_FROM_TMM(lchip)))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_tsingma_peri_set_mac_led_mode: ctl_id (%d) illegal!\n", p_led_para->ctl_id);
        return CTC_E_INVALID_PARAM;
    }

    if (SYS_CHIP_FLAG_ISSET(p_led_para->op_flag, SYS_CHIP_LED_MODE_SET_OP)
        || SYS_CHIP_FLAG_ISZERO(p_led_para->op_flag))
    {
    CTC_ERROR_RETURN(_sys_tsingma_peri_get_mac_led_mode_cfg(p_led_para->first_mode, &led_cfg));

    SetLedCfgPortMode(V, primaryLedMode_f, &led_mode, led_cfg);

    if (led_type == CTC_CHIP_USING_TWO_LED)
    {
        CTC_ERROR_RETURN(_sys_tsingma_peri_get_mac_led_mode_cfg(p_led_para->sec_mode, &led_cfg));
        SetLedCfgPortMode(V, secondaryLedMode_f, &led_mode, led_cfg);
        SetLedCfgPortMode(V, secondaryLedModeEn_f, &led_mode, 1);
    }

    cmd = DRV_IOW(LedCfgPortMode_t, DRV_ENTRY_FLAG);

    if (p_led_para->lport_en)
    {
        lport = p_led_para->port_id;
        MAC_LOCK;
        CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_get_gchip_id(lchip, &gchip_id));
        dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, lport);
        CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
        if ((port_type != SYS_DMPS_NETWORK_PORT)&&(port_type != SYS_DMPS_CPUMAC_NETWORK_PORT ))
        {
            MAC_UNLOCK;
            return CTC_E_INVALID_PARAM;
        }
        CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, (void *)&field_index));
        MAC_UNLOCK;
    }
    else
    {
        field_index = p_led_para->port_id;
    }
    if (DRV_IS_AT(lchip))
    {
        if (field_index >= SYS_CPU_MAC_ID_MAX) /* for breakout led */
        {
            CTC_MAX_VALUE_CHECK(field_index-SYS_CPU_MAC_ID_MAX, sizeof(break_led_id)/sizeof(break_led_id[0]));
            is_remote_core = p_led_para->ctl_id ? 1:0;
            field_index = break_led_id[field_index - SYS_CPU_MAC_ID_MAX-1];
        }
        else if (field_index >= SYS_CPU_MAC_ID_MIN)
        {
            is_remote_core = (field_index - SYS_CPU_MAC_ID_MIN) >= MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_CORE);
            field_index = (((field_index - SYS_CPU_MAC_ID_MIN) & 0x1) + 2);
        }
        else
        {
            is_remote_core = field_index >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_CORE);
            field_index = field_index % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_CORE);
            field_index = 156 - ((field_index>>3)<<3) + (field_index&0x7);
        }
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mac idx: %d\n", field_index);
        tmp_lchip = is_remote_core ? (SYS_PP_BASE(lchip) + SYS_CORE_PP_NUM(lchip)) : SYS_PP_BASE(lchip);
        CTC_ERROR_RETURN(DRV_IOCTL(tmp_lchip, field_index, DRV_CMD_PP_EN(cmd), &led_mode));
    }
    else
    {
        /* cpumac */
        if (field_index >= SYS_CPU_MAC_ID_MIN && field_index <= SYS_CPU_MAC_ID_MAX)
        {
            field_index = field_index - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP) - (p_led_para->ctl_id? MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP) : 0);
        }
        else if (field_index >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP))
        {
            field_index = field_index - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP);
        }
    field_index = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? DRV_INS(p_led_para->ctl_id, field_index) : field_index;
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, field_index, cmd, &led_mode));
    }
    }

    if (SYS_CHIP_FLAG_ISSET(p_led_para->op_flag, SYS_CHIP_LED_POLARITY_SET_OP)
        || SYS_CHIP_FLAG_ISZERO(p_led_para->op_flag))
    {
        /* set polarity for driving led 1: low driver led 0: high driver led */
        SetLedPolarityCfg(V, polarityInv_f, &led_polarity, p_led_para->polarity);
        cmd = DRV_IOW(LedPolarityCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? p_led_para->ctl_id : 0, cmd, &led_polarity));
    }
    return CTC_E_NONE;
}

int32
_sys_tsingma_peri_get_led_num(uint8 lchip, ctc_chip_mac_led_mapping_t* p_led_map, uint16 *p_led_num)
{
    int16 index = 0;
    int16 compare_index = 0;
    uint16 led_num = 0;
    uint16 cur_led_num = 0;
    uint16 cur_port_num = 0;

    /* get led number and sort */
   for (index = 1; index < p_led_map->mac_led_num ; index++)
   {
       cur_led_num = p_led_map->led_list[index];
       cur_port_num = p_led_map->port_list[index];
       for (compare_index = index - 1; compare_index >= 0 &&
           p_led_map->led_list[compare_index] > cur_led_num; compare_index--)
       {
           p_led_map->led_list[compare_index + 1] = p_led_map->led_list[compare_index];
           p_led_map->port_list[compare_index + 1] = p_led_map->port_list[compare_index];
       }
       p_led_map->led_list[compare_index + 1] = cur_led_num;
       p_led_map->port_list[compare_index + 1] = cur_port_num;
   }
    led_num = p_led_map->led_list[p_led_map->mac_led_num - 1] + 1;

    *p_led_num = led_num;

    return CTC_E_NONE;
}

/**
 @brief mac led interface for mac and led mapping
*/
int32
sys_tsingma_peri_set_mac_led_mapping(uint8 lchip, ctc_chip_mac_led_mapping_t* p_led_map)
{
    uint32 index = 0;
    uint32 cmd = 0;
    LedCfgPortSeqMap_m seq_map;
    LedPortRange_m port_range;
    uint16 lport = 0;
    uint16 led_num = 0;
    uint32 mac_id = 0;
    uint32 tbl_idx = 0;
    uint32 port_type = 0;
    uint8 gchip_id = 0;
    uint8 is_remote_core = 0;
    uint8 tmp_lchip = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sys_eunit_peri_led_cfg_t led_cfg;
    sys_eunit_peri_led_mapping_t led_mapping;
    uint16 core0_seq_index = 0;
    uint16 core1_seq_index = 0;
    uint16 break_led_id[] = {0,1,2,3,164,165,166,167}; /* reserved for breakout led */

    CTC_PTR_VALID_CHECK(p_led_map);
    if (NULL == p_led_map->p_mac_id && NULL == p_led_map->port_list)
    {
        return CTC_E_INVALID_PTR;
    }
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mac num:%d \n", p_led_map->mac_led_num);

    for (index = 0; index < p_led_map->mac_led_num; index++)
    {
        if (p_led_map->p_mac_id)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mac seq %d:%d;  ", index, p_led_map->p_mac_id[index]);
        }
        else
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "lport seq %d:%d;  ", index, p_led_map->port_list[index]);
        }
    }
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "\n");

    sal_memset(&seq_map, 0, sizeof(LedCfgPortSeqMap_m));
    sal_memset(&port_range, 0, sizeof(LedPortRange_m));

    if ((p_led_map->mac_led_num > DRV_TABLE_MAX_INDEX(lchip, LedCfgPortMode_t)) || (p_led_map->mac_led_num < 1))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_tsingma_peri_set_mac_led_mapping: mac_led_num (%d) illegal!\n", p_led_map->mac_led_num);
        return CTC_E_INVALID_PARAM;
    }

    if ((0 != p_led_map->ctl_id && DRV_IS_TSINGMA(lchip)) || ((p_led_map->ctl_id > 1) && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_tsingma_peri_set_mac_led_mode: ctl_id (%d) illegal!\n", p_led_map->ctl_id);
        return CTC_E_INVALID_PARAM;
    }
    if (!p_usw_peri_master[lchip]->is_cpu_led)
    {
        for (index = 0; index < p_led_map->mac_led_num; index++)
        {

            if (p_led_map->lport_en)
            {
                lport = (*((uint16*)p_led_map->port_list+ index));
                MAC_LOCK;
                CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_get_gchip_id(lchip, &gchip_id));
                dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, lport);
                CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
                if ((port_type != SYS_DMPS_NETWORK_PORT)&&(port_type != SYS_DMPS_CPUMAC_NETWORK_PORT ))
                {
                    MAC_UNLOCK;
                    return CTC_E_INVALID_PARAM;
                }
                CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, (void *)&mac_id));
                MAC_UNLOCK;
            }
            else
            {
                mac_id = *((uint8*)p_led_map->p_mac_id + index);
            }

            /*  for Arctic,
             *  Mac 0~7     -> LedMac 156 ~ 163
             *  Mac 8~15    -> LedMac 148 ~ 155
             *  Mac 16~23   -> LedMac 140 ~ 147
             ...
             *  Mac 152~159 -> LedMac 4 ~ 11
             * cpu Mac 320~321 -> LedMac 2 ~ 3
             */
            if (DRV_IS_AT(lchip))
            {
                if (mac_id >= SYS_CPU_MAC_ID_MIN)
                {
                    is_remote_core = (mac_id - SYS_CPU_MAC_ID_MIN) >= MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_CORE);
                    mac_id = (((mac_id - SYS_CPU_MAC_ID_MIN) & 0x1) + 2);
                }
                else
                {
                    is_remote_core = mac_id >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_CORE);
                    mac_id = mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_CORE);
                    mac_id = 156 - ((mac_id>>3)<<3) + (mac_id&0x7);
                }

                /* for Arctic, LED control 1 is on core 1 */
                cmd = DRV_IOW(LedCfgPortSeqMap_t, DRV_ENTRY_FLAG);
                SetLedCfgPortSeqMap(V, macId_f, &seq_map, mac_id);
                if (is_remote_core)
                {
                    tmp_lchip = SYS_PP_BASE(lchip) + SYS_CORE_PP_NUM(lchip);
                    CTC_ERROR_RETURN(DRV_IOCTL(tmp_lchip, core1_seq_index, DRV_CMD_PP_EN(cmd), &seq_map));
                    core1_seq_index++;
                }
                else
                {
                    tmp_lchip = SYS_PP_BASE(lchip);
                    CTC_ERROR_RETURN(DRV_IOCTL(tmp_lchip, core0_seq_index, DRV_CMD_PP_EN(cmd), &seq_map));
                    core0_seq_index++;
                }
            }
            /* for tsingma_mx, LED control 1 is on DP 1 */
            else
            {
                /* cpumac */
                if (mac_id >= SYS_CPU_MAC_ID_MIN && mac_id <= SYS_CPU_MAC_ID_MAX)
                {
                    mac_id = mac_id - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP) - (p_led_map->ctl_id? MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP) : 0);
                }
                else if (mac_id >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP))
                {
                    mac_id = mac_id - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP);
                }
                cmd = DRV_IOW(LedCfgPortSeqMap_t, DRV_ENTRY_FLAG);
                SetLedCfgPortSeqMap(V, macId_f, &seq_map, mac_id);
                tbl_idx = DRV_IS_TMM(lchip) ? DRV_INS(p_led_map->ctl_id, index) : index;
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, cmd, &seq_map));
            }
        }

        /* set MacLedPortRange */
        if (DRV_IS_AT(lchip))
        {
            SetLedPortRange(V, portStartIndex_f, &port_range, 0);
            cmd = DRV_IOW(LedPortRange_t, DRV_ENTRY_FLAG);
            SetLedPortRange(V, portEndIndex_f, &port_range, core0_seq_index - 1);
            CTC_ERROR_RETURN(DRV_IOCTL(SYS_PP_BASE(lchip) , 0, DRV_CMD_PP_EN(cmd), &port_range));
            if (core1_seq_index)
            {
                SetLedPortRange(V, portEndIndex_f, &port_range, core1_seq_index - 1);
                CTC_ERROR_RETURN(DRV_IOCTL(SYS_PP_BASE(lchip) + SYS_CORE_PP_NUM(lchip), 0, DRV_CMD_PP_EN(cmd), &port_range));
            }
        }
        else
        {
            SetLedPortRange(V, portStartIndex_f, &port_range, 0);
            SetLedPortRange(V, portEndIndex_f, &port_range, p_led_map->mac_led_num - 1);
            tbl_idx = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? p_led_map->ctl_id : 0;
            cmd = DRV_IOW(LedPortRange_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, tbl_idx, cmd, &port_range));
        }
    }
    else
    {
        if (NULL == p_led_map->port_list || NULL == p_led_map->led_list)
        {
            return CTC_E_INVALID_PTR;
        }
        sal_memset(&led_cfg, 0, sizeof(sys_eunit_peri_led_cfg_t));
        sal_memset(&led_mapping, 0, sizeof(sys_eunit_peri_led_mapping_t));

        led_cfg.mac_led_num = p_led_map->mac_led_num;
        /* get led num and sort by led num */
        CTC_ERROR_RETURN(_sys_tsingma_peri_get_led_num(lchip, p_led_map, &led_num));
        led_cfg.led_num = led_num;
        led_cfg.lport_en = p_led_map->lport_en;

        if (MCHIP_EUNIT(lchip) && MCHIP_EUNIT(lchip)->set_cfg)
        {
            CTC_ERROR_RETURN(MCHIP_EUNIT(lchip)->set_cfg(lchip, SYS_EUNIT_CFG_LED, &led_cfg));
        }
        /* per dp max support 684 port */
        for (index = 0; index < p_led_map->mac_led_num; index++)
        {
            led_mapping.led_id = p_led_map->led_list[index];
            led_mapping.port_id = p_led_map->port_list[index];
            if (DRV_IS_AT(lchip))
            {
                if (led_cfg.lport_en)
                {
                    lport = (*((uint16*)p_led_map->port_list+ index));
                    MAC_LOCK;
                    CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_get_gchip_id(lchip, &gchip_id));
                    dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, lport);
                    CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
                    if ((port_type != SYS_DMPS_NETWORK_PORT)&&(port_type != SYS_DMPS_CPUMAC_NETWORK_PORT ))
                    {
                        MAC_UNLOCK;
                        return CTC_E_INVALID_PARAM;
                    }
                    CTC_ERROR_RETURN_WITH_MAC_UNLOCK(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, (void *)&mac_id));
                    MAC_UNLOCK;
                }
                else
                {
                    mac_id = led_mapping.port_id;
                }
                if (mac_id > SYS_CPU_MAC_ID_MAX) /* for breakout led */
                {
                    CTC_MAX_VALUE_CHECK(mac_id-SYS_CPU_MAC_ID_MAX, sizeof(break_led_id)/sizeof(break_led_id[0]));
                    is_remote_core = p_led_map->ctl_id ? 1:0;
                    mac_id = break_led_id[mac_id - SYS_CPU_MAC_ID_MAX-1];
                }
                else if (mac_id >= SYS_CPU_MAC_ID_MIN)
                {
                    is_remote_core = (mac_id - SYS_CPU_MAC_ID_MIN) >= MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_CORE);
                    mac_id = (((mac_id - SYS_CPU_MAC_ID_MIN) & 0x1) + 2);
                }
                else
                {
                    is_remote_core = mac_id >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_CORE);
                    mac_id = mac_id % MCHIP_CAP(SYS_CAP_MAC_NUM_PER_CORE);
                    mac_id = 156 - ((mac_id>>3)<<3) + (mac_id&0x7);
                }
                mac_id |= (is_remote_core << 15);/* use mac id bit15 carry core id */
                led_mapping.port_id = mac_id;
            }

            if (MCHIP_EUNIT(lchip) && MCHIP_EUNIT(lchip)->set_cfg)
            {
                CTC_ERROR_RETURN(MCHIP_EUNIT(lchip)->set_cfg(lchip, SYS_EUNIT_CFG_LED_MAPPING, &led_mapping));
            }
        }

        /* set MacLedPortRange */
        SetLedPortRange(V, portStartIndex_f, &port_range, 0);
        if ((led_num) % SYS_TSINGMA_LED_NUMBER_PER_TABLE)
        {
            SetLedPortRange(V, portEndIndex_f, &port_range, (led_num / SYS_TSINGMA_LED_NUMBER_PER_TABLE));
        }
        else
        {
            SetLedPortRange(V, portEndIndex_f, &port_range, (led_num / SYS_TSINGMA_LED_NUMBER_PER_TABLE - 1));
        }
        /* for Arctic, LED control 1 is on core 1, for tsingma_mx, LED control 1 is on DP 1 (instance 1) */
        tbl_idx = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? p_led_map->ctl_id : 0;
        tmp_lchip = (DRV_IS_AT(lchip) && p_led_map->ctl_id) ? (SYS_PP_BASE(lchip) + SYS_CORE_PP_NUM(lchip)) : SYS_PP_BASE(lchip);
        cmd = DRV_IOW(LedPortRange_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(tmp_lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &port_range));
    }
    return CTC_E_NONE;
}

/**
 @brief begin mac led function
*/
int32
sys_tsingma_peri_set_mac_led_en(uint8 lchip, bool enable)
{
    uint32 cmd = 0;
    LedSampleInterval_m led_sample;
    LedRawStatusCfg_m raw_cfg;
    LedCfgCalCtl_m cal_ctrl;
    LedLightMode_m led_mode;
    uint32 field_value = (TRUE == enable) ? 1 : 0;
    uint32 refresh_interval = 0x27ffff6;
    uint32 sample_interval = 0x27ffff6;
    uint8 ctl_id = 0;
    uint8 ctl_num = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mac led Enable enable:%d\n", ((TRUE == enable) ? 1 : 0));

    sal_memset(&led_sample, 0, sizeof(LedSampleInterval_m));
    sal_memset(&raw_cfg, 0, sizeof(LedRawStatusCfg_m));
    sal_memset(&cal_ctrl, 0, sizeof(LedCfgCalCtl_m));
    sal_memset(&led_mode, 0, sizeof(led_mode));

    if (DRV_FROM_AT(lchip))
    {
        uint32 clock1msThrd = 0;/* set to zero, RefreshInterval/BlinkInterval/SampleInterval unit is cycle of clockCore @1.35 GHz */
        refresh_interval = 0x405f7e0;/* 50 ms units: cycle of clockCore @1.35 GHz */
        sample_interval = 0x1A26CB30;      /* (50 * 6.5) ms units: cycle of clockCore @1.35 GHz */
        cmd = DRV_IOW(LedRefreshInterval_t, LedRefreshInterval_clock1msThrd_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, ctl_id, cmd, &clock1msThrd));
    }
    else
    {
        refresh_interval = 0x27ffff6;
        sample_interval = 0x1039de00;
    }

    ctl_num = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))?2:1;
    for (ctl_id = 0; ctl_id < ctl_num; ctl_id++)
    {
        cmd = DRV_IOW(LedCfgCalCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, ctl_id, cmd, &cal_ctrl));

        cmd = DRV_IOR(LedSampleInterval_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, ctl_id, cmd, &led_sample));

        SetLedSampleInterval(V, histogramEn_f, &led_sample, field_value);
        SetLedSampleInterval(V, sampleEn_f, &led_sample, field_value);
        SetLedSampleInterval(V, sampleInterval_f, &led_sample, sample_interval);

        cmd = DRV_IOW(LedSampleInterval_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, ctl_id, cmd, &led_sample));

        cmd = DRV_IOW(LedRefreshInterval_t, LedRefreshInterval_refreshEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, ctl_id, cmd, &field_value));

        cmd = DRV_IOW(LedRefreshInterval_t, LedRefreshInterval_refreshInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, ctl_id, cmd, &refresh_interval));

        SetLedLightMode(V, cpuMode_f, &led_mode, (p_usw_peri_master[lchip]->is_cpu_led && enable)? enable: 0);
        cmd = DRV_IOW(LedLightMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, ctl_id, cmd, &led_mode));

        SetLedRawStatusCfg(V, rawStatusEn_f, &raw_cfg, (p_usw_peri_master[lchip]->is_cpu_led && enable)? enable: 0);
        cmd = DRV_IOW(LedRawStatusCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, ctl_id, cmd, &raw_cfg));
    }

    /* LED interface need be sync the phase of LED out put */
    if (DRV_FROM_AT(lchip))
    {
        cmd = DRV_IOW(LedCntSync_t, LedCntSync_ledCntSync_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    }
    else if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cmd = DRV_IOW(CtcMiscCtl_t, CtcMiscCtl_ledCntSync_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    }
    return CTC_E_NONE;
}

/**
 @brief get mac led function
*/
int32
sys_tsingma_peri_get_mac_led_en(uint8 lchip, bool* enable)
{
    uint32 cmd = 0;
    uint32 field_value = 0;

    CTC_PTR_VALID_CHECK(enable);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    cmd = DRV_IOR(LedRefreshInterval_t, LedRefreshInterval_refreshEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get mac led Enable enable:%d\n", field_value);

    *enable = field_value;

    return CTC_E_NONE;
}

int32
sys_tsingma_peri_set_mac_led_clock(uint8 lchip, uint16 freq)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint32 core_freq = 0;
    uint32 get_freq = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    core_freq = DRV_IS_AT(lchip) ? sys_usw_get_core_freq(lchip, 1) : sys_usw_get_core_freq(lchip, 0);

    field_value = (core_freq*1000/freq);
    if(0xffff < field_value)
    {
        return CTC_E_INVALID_PARAM;
    }

    get_freq = (core_freq * 1000 / field_value);
    CTC_MAX_VALUE_CHECK(get_freq, CTC_MAX_UINT16_VALUE);

    cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgClkLedDiv_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    /*
        #2, Toggle the clockLed divider reset
            cfg SupDskCfg.cfgResetClkLedDiv = 1'b1;
            cfg SupDskCfg.cfgResetClkLedDiv = 1'b0;
    */
    field_value = 1;
    cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkLedDiv_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    field_value = 0;
    cmd = DRV_IOW(SupDskCfg_t, SupDskCfg_cfgResetClkLedDiv_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    return CTC_E_NONE;
}

int32
sys_tsingma_peri_get_mac_led_clock(uint8 lchip, uint16* freq)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 core_freq = 0;

    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((SDK_WORK_PLATFORM != 0) || (DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    core_freq = DRV_IS_AT(lchip) ? sys_usw_get_core_freq(lchip, 1) : sys_usw_get_core_freq(lchip, 0);

    cmd = DRV_IOR(SupDskCfg_t, SupDskCfg_cfgClkLedDiv_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    *freq = (core_freq*1000)/field_val;

    return CTC_E_NONE;
}

#define __GPIO_INTERFACE__

/**
 @brief gpio interface
*/
int32
sys_tsingma_peri_set_gpio_mode(uint8 lchip, uint8 gpio_id, ctc_chip_gpio_mode_t mode)
{
    uint32 cmd = 0;
    uint32 tbl_out_id = 0;
    uint32 tbl_intr_id = 0;
    uint32 tbl_intr_level_id = 0;
    uint32 field_out_id = 0;
    uint32 field_intr_id = 0;
    uint32 field_intr_level_id = 0;
    uint32 field_out_val = 0;
    uint32 field_intr_val = 0;
    uint32 field_intr_level_val = 0;
    uint8 gpio_act_id = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "set gpio mode, gpio_id:%d mode:%d\n", gpio_id, mode);

    if (gpio_id >= SYS_PERI_HS_MAX_GPIO_ID)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "gpio_id:%d over max gpio id\n", gpio_id);
        return CTC_E_INVALID_PARAM;
    }

    if ((mode == CTC_CHIP_LEVEL_INTR_INPUT_MODE) && (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    if (SYS_PERI_GPIO_IS_HS(gpio_id))
    {
        gpio_act_id = gpio_id-SYS_PERI_MAX_GPIO_ID;
        tbl_out_id = DRV_FROM_TMM(lchip)?ScpuGpioOutEn_t:GpioHsOutCtl_t;
        field_out_id = DRV_FROM_TMM(lchip)?ScpuGpioOutEn_cfgGpioOutEn_f:GpioHsOutCtl_cfgHsOutEn_f;
        tbl_intr_id = DRV_FROM_TMM(lchip)?ScpuGpioIntrEn_t:GpioHsIntrEn_t;
        field_intr_id = DRV_FROM_TMM(lchip)?ScpuGpioIntrEn_cfgGpioIntrEn_f:GpioHsIntrEn_cfgHsIntrEn_f;
        tbl_intr_level_id = GpioHsIntrLevel_t;
        field_intr_level_id = GpioHsIntrLevel_cfgHsIntrLevel_f;
    }
    else
    {
        gpio_act_id = gpio_id;
        tbl_out_id = DRV_FROM_TMM(lchip)?EcpuGpioOutEn_t:GpioOutCtl_t;
        field_out_id = DRV_FROM_TMM(lchip)?EcpuGpioOutEn_cfgGpioOutEn_f:GpioOutCtl_cfgOutEn_f;
        tbl_intr_id = DRV_FROM_TMM(lchip)?EcpuGpioIntrEn_t:GpioIntrEn_t;
        field_intr_id = DRV_FROM_TMM(lchip)?EcpuGpioIntrEn_cfgGpioIntrEn_f:GpioIntrEn_cfgIntrEn_f;
        tbl_intr_level_id = GpioIntrLevel_t;
        field_intr_level_id = GpioIntrLevel_cfgIntrLevel_f;
    }

    cmd = DRV_IOR(tbl_out_id, field_out_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_out_val));
    cmd = DRV_IOR(tbl_intr_id, field_intr_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_intr_val));
    cmd = DRV_IOR(tbl_intr_level_id, field_intr_level_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_intr_level_val));

    switch(mode)
    {
        case CTC_CHIP_INPUT_MODE:
            CTC_BIT_UNSET(field_out_val, gpio_act_id);
            CTC_BIT_UNSET(field_intr_val, gpio_act_id);
            CTC_BIT_UNSET(field_intr_level_val, gpio_act_id);
            break;
        case CTC_CHIP_OUTPUT_MODE:
            CTC_BIT_SET(field_out_val, gpio_act_id);
            CTC_BIT_UNSET(field_intr_val, gpio_act_id);
            CTC_BIT_UNSET(field_intr_level_val, gpio_act_id);
            break;
        case CTC_CHIP_EDGE_INTR_INPUT_MODE:
            CTC_BIT_UNSET(field_out_val, gpio_act_id);
            CTC_BIT_SET(field_intr_val, gpio_act_id);
            CTC_BIT_UNSET(field_intr_level_val, gpio_act_id);
            break;
        case CTC_CHIP_LEVEL_INTR_INPUT_MODE:
            CTC_BIT_UNSET(field_out_val, gpio_act_id);
            CTC_BIT_SET(field_intr_val, gpio_act_id);
            CTC_BIT_SET(field_intr_level_val, gpio_act_id);
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    cmd = DRV_IOW(tbl_out_id, field_out_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_out_val));
    cmd = DRV_IOW(tbl_intr_id, field_intr_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_intr_val));
    cmd = DRV_IOW(tbl_intr_level_id, field_intr_level_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_intr_level_val));

    return CTC_E_NONE;
}

/**
 @brief gpio output
*/
int32
sys_tsingma_peri_set_gpio_output(uint8 lchip, uint8 gpio_id, uint8 out_para)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 tbl_id = 0;
    uint32 field_id = 0;
    uint8 gpio_act_id = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "set gpio out, gpio_id:%d out_para:%d\n", gpio_id, out_para);

    if (gpio_id >= SYS_PERI_HS_MAX_GPIO_ID)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "gpio_id:%d over max gpio id\n", gpio_id);
        return CTC_E_INVALID_PARAM;
    }
    if (SYS_PERI_GPIO_IS_HS(gpio_id))
    {
        gpio_act_id = gpio_id-SYS_PERI_MAX_GPIO_ID;
        tbl_id = DRV_FROM_TMM(lchip)?ScpuGpioOut_t:GpioHsDataCtl_t;
        field_id = DRV_FROM_TMM(lchip)?ScpuGpioOut_cfgGpioOut_f:GpioHsDataCtl_cfgHsData_f;
    }
    else
    {
        gpio_act_id = gpio_id;
        tbl_id = DRV_FROM_TMM(lchip)?EcpuGpioOut_t:GpioDataCtl_t;
        field_id = DRV_FROM_TMM(lchip)?EcpuGpioOut_cfgGpioOut_f:GpioDataCtl_cfgData_f;
    }

    cmd = DRV_IOR(tbl_id, field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    if (out_para)
    {
        CTC_BIT_SET(field_val, gpio_act_id);
    }
    else
    {
        CTC_BIT_UNSET(field_val, gpio_act_id);
    }
    cmd = DRV_IOW(tbl_id, field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    return CTC_E_NONE;
}

/**
 @brief gpio input
*/
int32
sys_tsingma_peri_get_gpio_input(uint8 lchip, uint8 gpio_id, uint8* in_value)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 tbl_id = 0;
    uint32 field_id = 0;
    uint8 gpio_act_id = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (gpio_id >= SYS_PERI_HS_MAX_GPIO_ID)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "gpio_id:%d over max gpio id\n", gpio_id);
        return CTC_E_INVALID_PARAM;
    }
    if (SYS_PERI_GPIO_IS_HS(gpio_id))
    {
        gpio_act_id = gpio_id-SYS_PERI_MAX_GPIO_ID;
        tbl_id = DRV_FROM_TMM(lchip)?ScpuGpioIn_t:GpioHsReadData_t;
        field_id = DRV_FROM_TMM(lchip)?ScpuGpioIn_gpioIn_f:GpioHsReadData_gpioHsReadData_f;
    }
    else
    {
        gpio_act_id = gpio_id;
        tbl_id = DRV_FROM_TMM(lchip)?EcpuGpioIn_t:GpioReadData_t;
        field_id = DRV_FROM_TMM(lchip)?EcpuGpioIn_gpioIn_f:GpioReadData_gpioReadData_f;
    }

    cmd = DRV_IOR(tbl_id, field_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    if (CTC_IS_BIT_SET(field_val, gpio_act_id))
    {
        *in_value = TRUE;
    }
    else
    {
        *in_value = FALSE;
    }

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "get gpio in, gpio_id:%d in_para:%d\n", gpio_id, *in_value);
    return CTC_E_NONE;
}

#define __INIT__

STATIC int32
_sys_tsingma_peri_led_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    ds_t ds;

    /*
       1. cfg default LED clock @25MHz & reset LED module
    */
    CTC_ERROR_RETURN(sys_tsingma_peri_set_mac_led_clock(lchip, 25000));

    field_value = 0;
    cmd = DRV_IOW(CtcBufStoreProcTopCtlReset_t, CtcBufStoreProcTopCtlReset_resetCoreLed_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    /* 2. reset CPU MAC */
    cmd = DRV_IOR(CtcMiscCtlReset_t,DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip,0, cmd, &ds));
    SetCtcMiscCtlReset(V, resetCoreCpuMac_f , &ds, field_value);
    cmd = DRV_IOW(CtcMiscCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds))

    /* 3. cfg defualt blink interval */
    /* For Arctic units is ms, For other chip units is cycle of clockCore */
    field_value =  0x0d1cef00;
    cmd = DRV_IOW(LedBlinkCfg_t, LedBlinkCfg_blinkOffInterval_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    cmd = DRV_IOW(LedBlinkCfg_t, LedBlinkCfg_blinkOnInterval_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cmd = DRV_IOW(LedBlinkCfg_t, LedBlinkCfg_blinkOffInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 1, cmd, &field_value));
        cmd = DRV_IOW(LedBlinkCfg_t, LedBlinkCfg_blinkOnInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 1, cmd, &field_value));
    }

    if (DRV_FROM_TMM(lchip))
    {
        if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
        {
            cmd = DRV_IOR(LedLightMode_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));
            p_usw_peri_master[lchip]->is_cpu_led = GetLedLightMode(V, cpuMode_f, &ds);
        }
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_peri_i2c_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 field_value = 0;

    /*
        #1, Cfg I2C interface MSCL clock Frequency=25KHz, supper super freq @500MHz
            TMM i2c master clock divider from clockSup 800M or 500M, default is 800M
            Arctic i2c master clock divider from clockSup 950M
    */

    field_value = MCHIP_CAP(SYS_CAP_I2C_REF_CLOCK) * 1000 / 25;
    cmd = DRV_IOW(I2CMasterCfg0_t, I2CMasterCfg0_clkDiv_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    cmd = DRV_IOW(I2CMasterCfg1_t, I2CMasterCfg0_clkDiv_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    field_value = 1;
    cmd = DRV_IOW(I2CMasterInit0_t, I2CMasterInit0_init_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    field_value = 1;
    cmd = DRV_IOW(I2CMasterInit1_t, I2CMasterInit1_init_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    return CTC_E_NONE;
}

int32
sys_tsingma_peri_mdio_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    ctc_chip_phy_scan_ctrl_t scan_ctl;
    uint16 mac_id = 0;
    MdioChanMap_m mdio_map;
    MdioCfg0_m mdio_cfg;
    uint32 value = 0;
    uint32 chan_id = 0;
    uint8 gchip_id = 0;
    uint16 lport = 0;
    uint8 index = 0;
    int32 ret = CTC_E_NONE;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    sal_memset(&scan_ctl , 0, sizeof(ctc_chip_phy_scan_ctrl_t));

    for (index = 0; index < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); index++)
    {
        cmd = DRV_IOW(MdioCfg0_t, DRV_ENTRY_FLAG);
        SetMdioCfg0(V, mdioCmdDoneIntervalLane0_f, &mdio_cfg, 0x0a);
        SetMdioCfg0(V, mdioInDlyLane0_f, &mdio_cfg, 0x09);
        SetMdioCfg0(V, mdioIsXgModeLane0_f, &mdio_cfg, 0);
        SetMdioCfg0(V, mdioMacPreLane0_f, &mdio_cfg, 0x1f);
        DRV_IOCTL(lchip, index, cmd, &mdio_cfg);
        cmd = DRV_IOW(MdioCfg1_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, cmd, &mdio_cfg);
    }

    /*
        1. cfg default MDC clock @2.5 MHz & reset MDIO module
    */
    sys_tsingma_peri_set_mdio_clock(lchip, CTC_CHIP_MDIO_GE, 2500);

    field_value = 0;
    cmd = DRV_IOW(SupResetCtl_t, SupResetCtl_resetMdio_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    field_value = 1;
    cmd = DRV_IOW((MdioInit_t), MdioInit_init_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value);

    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        MdioMiscCtl_m mdio_misc;
        uint32 phy_port_array[MAX_PORT_NUM_PER_CHIP/32] = {0};
        field_value = 1;
        cmd = DRV_IOW((MdioInit_t), MdioInit_init_f);
        DRV_FIELD_IOCTL(lchip, 1, cmd, &field_value);

        cmd = DRV_IOR(MdioMiscCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &mdio_misc);
        sal_memset(phy_port_array, 0xff, sizeof(phy_port_array));
        SetMdioMiscCtl(A, linkDownDlbDetc_f, &mdio_misc, phy_port_array);
        SetMdioMiscCtl(A, linkDownIgnorMask_f, &mdio_misc, phy_port_array);
        SetMdioMiscCtl(A, linkDownIpeFwdDetc_f, &mdio_misc, phy_port_array);
        SetMdioMiscCtl(A, linkDownMetDetc_f, &mdio_misc, phy_port_array);
        SetMdioMiscCtl(A, linkDownQMgrDetc_f, &mdio_misc, phy_port_array);
        cmd = DRV_IOW(MdioMiscCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &mdio_misc);

        cmd = DRV_IOW(MdioMiscCtl_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 1, cmd, &mdio_misc);
    }
    /*
        MdioLinkDownDetecEn0_linkDownDetcEn_f
    */
    /* cmd = DRV_IOW(MdioLinkDownDetecEn0_t, MdioLinkDownDetecEn0_linkDownDetcEn_f);*/
    /* CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, detect_en));*/
    /* cmd = DRV_IOW(MdioLinkDownDetecEn1_t, MdioLinkDownDetecEn1_linkDownDetcEn_f);*/
    /* CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, detect_en));*/

    /*
        Init mdio scan. For no phy on demo board, just set interval
    */
    for (index = 0; index < MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM); index++)
    {
        scan_ctl.op_flag = CTC_CHIP_INTERVAL_OP;
        scan_ctl.scan_interval = 100;
        scan_ctl.mdio_ctlr_id = index;
        CTC_ERROR_RETURN(sys_tsingma_peri_set_phy_scan_para(lchip, &scan_ctl));
    }
    CTC_ERROR_RETURN(sys_tsingma_peri_set_phy_scan_cfg(lchip));

    /*cfg mdio channel map*/
    sal_memset(&mdio_map, 0, sizeof(MdioChanMap_m));
    for (mac_id = 0; mac_id < (MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP)+MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP))*MCHIP_CAP(SYS_CAP_DP_MAX_NUM); mac_id++)
    {
        uint16 phy_mac_id = 0;
        lport = sys_usw_datapath_get_lport_with_mac(lchip, mac_id);
        CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip_id));
        dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, lport);
        ret = sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, (void *)&chan_id);
        if (ret)
        {
            continue;
        }
        ret = sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, (void *)&value);
        if (ret)
        {
            continue;
        }
        if (value >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP)*MCHIP_CAP(SYS_CAP_DP_MAX_NUM))
        {/* cpumac */
            uint8 dp_id = 0;
            dp_id = (value - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP)*MCHIP_CAP(SYS_CAP_DP_MAX_NUM)) / MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP);
            phy_mac_id = MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP)+dp_id*MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP) + (value - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP)*MCHIP_CAP(SYS_CAP_DP_MAX_NUM));
        }
        else
        {
            phy_mac_id = (value >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP))?
                (162+(value%MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP))):value;
        }
        SetMdioChanMap(V, chanId_f, &mdio_map, chan_id);
        cmd = DRV_IOW((MdioChanMap_t), DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, phy_mac_id, DRV_CMD_PP_EN(cmd), &mdio_map);
    }

    sys_usw_peri_set_phy_scan_en(lchip, TRUE);

    return CTC_E_NONE;
}

int32
sys_tsingma_peri_init(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    ds_t ds;
    /*
        1. RlmBsr RLM level reset
    */
    cmd = DRV_IOR(SupResetCtl_t,DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip,0, cmd, &ds));
    field_value = 0;
    SetSupResetCtl(V, cfgRstRlmMiscSlice0_f , &ds, field_value);
    cmd = DRV_IOW(SupResetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ds));

    field_value = 0;
    cmd = DRV_IOW(SupResetCtl_t, SupResetCtl_resetRlmBsr_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    /* 2. cfg MAC LED default clock, reset LED Module */
    CTC_ERROR_RETURN(_sys_tsingma_peri_led_init(lchip));

    /* 3. cfg i2c default clock, reset i2c Module */
    CTC_ERROR_RETURN(_sys_tsingma_peri_i2c_init(lchip));

    /*CTC_ERROR_RETURN(sys_tsingma_peri_mdio_init(lchip));*/

    return CTC_E_NONE;
}

#define __OTHER_INTERFACE__

STATIC int32
_sys_tsingma_peri_get_temp_with_code(uint8 lchip, uint32 temp_code, uint32* p_temp_val)
{
    uint16 temp_mapping_tbl[SYS_TSINGMA_TEMP_TABLE_NUM+1] = {
        804, 801, 798, 795, 792, 790, 787, 784, 781, 778, 775, 772, 769, 766, 763, 761, 758, 755, 752, 749, /*-40~-21*/
        746, 743, 740, 737, 734, 731, 728, 725, 722, 719, 717, 714, 711, 708, 705, 702, 699, 696, 693, 690, /*-20~-1*/
        687, 684, 681, 678, 675, 672, 669, 666, 663, 660, 658, 655, 652, 649, 646, 643, 640, 637, 634, 631, /*0~19*/
        628, 625, 622, 619, 616, 613, 610, 607, 604, 601, 599, 596, 593, 590, 587, 584, 581, 578, 575, 572, /*20~39*/
        569, 566, 563, 560, 557, 554, 551, 548, 545, 542, 540, 537, 534, 531, 528, 525, 522, 519, 516, 513, /*40~59*/
        510, 507, 504, 501, 498, 495, 492, 489, 486, 483, 481, 478, 475, 472, 469, 466, 463, 460, 457, 454, /*60~79*/
        451, 448, 445, 442, 439, 436, 433, 430, 427, 424, 421, 418, 415, 412, 409, 406, 403, 400, 397, 394, /*80~99*/
        391, 388, 385, 382, 379, 376, 373, 370, 367, 364, 361, 358, 355, 352, 349, 346, 343, 340, 337, 334, /*100~119*/
        331, 328, 325, 322, 319, 316, 0};                                                                   /*120~125*/
    uint8 index = 0;

    /*if ((temp_code > temp_mapping_tbl[0]) || (temp_code < temp_mapping_tbl[SYS_TSINGMA_TEMP_TABLE_NUM-1]))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "temp code error %d\n", temp_code);
        return CTC_E_HW_INVALID_INDEX;
    }*/

    for (index = 0; index< SYS_TSINGMA_TEMP_TABLE_NUM; index++)
    {
        if ((temp_code <= temp_mapping_tbl[index]) && (temp_code > temp_mapping_tbl[index+1]))
        {
            break;
        }
    }

    if (index < SYS_TSINGMA_ZERO_TEMP_INDEX)
    {
        *p_temp_val = SYS_TSINGMA_ZERO_TEMP_INDEX - index + (1 << 31);
    }
    else
    {
        *p_temp_val = index - SYS_TSINGMA_ZERO_TEMP_INDEX;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_tsingma_peri_get_chip_sensor(uint8 lchip, ctc_chip_sensor_type_t type, uint32* p_value)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
    uint32 index = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_value);

    if ((CTC_CHIP_SENSOR_TEMP != type) && (CTC_CHIP_SENSOR_VOLTAGE != type))
    {
        return CTC_E_INVALID_PARAM;
    }
    /*config RCLK_EN=1,RAVG_SEL,RCLK_DIV*/
    /*mask_write tbl-reg OmcMem 0xf offset 0x0 0x00001000 0x00001000*/
    index = 0xf;
    //cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    //CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    field_val = 0x310c7;
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));

    /*config RTHMC_RST=1*/
    /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000010 0x00000010*/
    index = 0x10;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    CTC_BIT_SET(field_val, 4);
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));

    /*wait RTHMC_RST=1*/
    /*read tbl-reg OmcMem 0x10 offset 0x0*/
    timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
    index = 0x10;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    while(timeout)
    {
        timeout--;
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        if (0 == CTC_IS_BIT_SET(field_val, 4))
        {
            break;
        }
        sal_task_sleep(1);
    }
    if (0 == timeout)
    {
        return CTC_E_HW_TIME_OUT;
    }

    /*config ENBIAS=1��ENVR=1��ENAD=1*/
    /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x02000007 0x03000007*/
    index = 0x11;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    CTC_BIT_SET(field_val, 0);
    CTC_BIT_SET(field_val, 1);
    CTC_BIT_SET(field_val, 2);
    CTC_BIT_UNSET(field_val, 24);
    CTC_BIT_SET(field_val, 25);
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));

    sal_task_sleep(10);

    /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
    /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000003*/
    /*mask_write tbl-reg OmcMem 0x8 offset 0x0 0x00000004 0x00000004*/
    /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001*/
    index = 0x10;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    CTC_BIT_SET(field_val, 0);
    CTC_BIT_SET(field_val, 1);
    CTC_BIT_SET(field_val, 9);
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    index = 0x8;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    CTC_BIT_SET(field_val, 2);
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    index = 0x12;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    CTC_BIT_SET(field_val, 0);
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));

    if (CTC_CHIP_SENSOR_TEMP == type)
    {
        /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000001 0x00000001*/
        index = 0x10;
        cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        CTC_BIT_SET(field_val, 0);
        cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    }
    else
    {
        /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000000 0x00000001*/
        index = 0x10;
        cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        CTC_BIT_UNSET(field_val, 0);
        cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    }
    sal_task_sleep(10);

    /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001*/
    index = 0x12;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    CTC_BIT_SET(field_val, 0);
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));


    /*Wait((mask_read tbl-reg OmcMem 0xa offset 0x0 0x00000004) =1)*/
    index = 0xa;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
    while(timeout)
    {
        timeout--;
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        if (CTC_IS_BIT_SET(field_val, 2))
        {
            break;
        }
        sal_task_sleep(1);
    }
    if (0 == timeout)
    {
        return CTC_E_HW_TIME_OUT;
    }

    /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x00000006 0x00000006*/
    index = 0x11;
    cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    CTC_BIT_SET(field_val, 1);
    CTC_BIT_SET(field_val, 2);
    cmd = DRV_IOW(OmcMem_t, OmcMem_data_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
    sal_task_sleep(10);

    if (CTC_CHIP_SENSOR_TEMP == type)
    {
        /*read-reg OmcMem 0xd offset 0x0*/
        index = 0xd;
        cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        CTC_ERROR_RETURN(_sys_tsingma_peri_get_temp_with_code(lchip, field_val, p_value));
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "temp code %d\n", field_val);
    }
    else
    {
        /*read-reg OmcMem 0xc offset 0x0*/
        index = 0xc;
        cmd = DRV_IOR(OmcMem_t, OmcMem_data_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "voltage code %d\n", field_val);
        *p_value =  (field_val*1232)/1023;
    }

    return CTC_E_NONE;
}

int32
sys_tsingma_peri_get_chip_sensor(uint8 lchip, void* sensor)
{
    ctc_chip_sensor_t* p_sensor = (ctc_chip_sensor_t* )sensor;

    CTC_ERROR_RETURN(_sys_tsingma_peri_get_chip_sensor(lchip, p_sensor->type, &p_sensor->value[0]));
    p_sensor->count = 1;

    return CTC_E_NONE;
}

STATIC int32
_sys_tmm_peri_get_temp_with_code(uint8 lchip, uint32 temp_code, uint32* p_temp_val)
{
    uint16 temp_mapping_tbl[SYS_TEMP_TABLE_NUM+1] = {
        778, 775, 772, 768, 765, 762, 759, 756, 752, 749, 746, 743, 739, 736, 733, 730, 726, 723, 720, 716,  /*-40~-21*/
        713, 710, 707, 703, 700, 697, 694, 691, 687, 684, 681, 678, 675, 671, 668, 665, 662, 659, 655, 652,  /*-20~-1*/
        649, 646, 642, 639, 636, 633, 629, 626, 623, 619, 616, 613, 609, 606, 603, 600, 596, 593, 590, 586,  /*0~19*/
        583, 580, 576, 573, 570, 567, 563, 560, 557, 553, 550, 547, 543, 540, 537, 534, 530, 527, 524, 520,  /*20~39*/
        517, 514, 510, 507, 504, 500, 497, 494, 490, 487, 484, 480, 477, 473, 470, 467, 463, 460, 457, 453,  /*40~59*/
        450, 447, 443, 440, 436, 433, 430, 426, 423, 419, 416, 413, 409, 406, 402, 399, 396, 392, 389, 385,  /*60~79*/
        382, 379, 375, 372, 368, 365, 362, 358, 355, 351, 348, 345, 341, 338, 334, 331, 328, 324, 321, 317,  /*80~99*/
        314, 310, 307, 303, 300, 296, 293, 289, 286, 282, 279, 276, 272, 269, 265, 262, 258, 255, 251, 248,  /*100~119*/
        244, 241, 237, 234, 230, 227, 0};                                                                   /*120~125*/
    uint8 index = 0;

    for (index = 0; index< SYS_TEMP_TABLE_NUM; index++)
    {
        if ((temp_code <= temp_mapping_tbl[index]) && (temp_code > temp_mapping_tbl[index+1]))
        {
            break;
        }
    }

    if (index < SYS_TSINGMA_ZERO_TEMP_INDEX)
    {
        *p_temp_val = SYS_TSINGMA_ZERO_TEMP_INDEX - index + (1 << 31);
    }
    else
    {
        *p_temp_val = index - SYS_TSINGMA_ZERO_TEMP_INDEX;
    }

    return CTC_E_NONE;
}


int32
sys_tmm_peri_get_chip_sensor(uint8 lchip, void* sensor_value)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
    uint32 index = 0;
    ds_t    ds;
    uint8  loop = 0;
    uint32 sensor[CTC_MAX_CHIP_SENSOR] = {OmcMemTL_t,OmcMemTR_t,OmcMemBL_t,OmcMemBL_t, OmcMemBR_t,OmcMemBR_t};
    ctc_chip_sensor_t* p_value = (ctc_chip_sensor_t*)sensor_value;
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_value);

    if ((CTC_CHIP_SENSOR_TEMP != p_value->type) && (CTC_CHIP_SENSOR_VOLTAGE != p_value->type))
    {
        return CTC_E_INVALID_PARAM;
    }
    /*
    tmm temperature max return 4 value,  voltage max return 6 value
    other chip this capability maybe change need double check
    */
    p_value->count = (CTC_CHIP_SENSOR_TEMP == p_value->type) ? MCHIP_CAP(SYS_CAP_CHIP_TEMP_SENSOR_NUM) : \
                                                               MCHIP_CAP(SYS_CAP_CHIP_VOL_SENSOR_NUM);
    for (loop=0; loop < p_value->count; loop++)
    {
        index = 0xf;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = 0x313ff;
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        /*config RTHMC_RST=1*/
        /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000010 0x00000010*/
        index = 0x10;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = GetOmcMemTL(V, data_f, &ds);
        CTC_BIT_SET(field_val, 4);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        /*wait RTHMC_RST=1*/
        /*read tbl-reg OmcMem 0x10 offset 0x0*/
        timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
        index = 0x10;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        while(timeout)
        {
            timeout--;
            CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
            field_val = GetOmcMemTL(V, data_f, &ds);
            if (0 == CTC_IS_BIT_SET(field_val, 4))
            {
                break;
            }
            sal_task_sleep(1);
        }
        if (0 == timeout)
        {
            return CTC_E_HW_TIME_OUT;
        }
        /*config ENBIAS=1ENVR=1ENAD=1*/
        /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x02000007 0x03000007*/
        index = 0x11;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = GetOmcMemTL(V, data_f, &ds);
        CTC_BIT_SET(field_val, 0);
        CTC_BIT_SET(field_val, 1);
        CTC_BIT_SET(field_val, 2);
        CTC_BIT_UNSET(field_val, 24);
        CTC_BIT_SET(field_val, 25);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        sal_task_sleep(10);

        index = 0x10;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = GetOmcMemTL(V, data_f, &ds);
        CTC_BIT_SET(field_val, 1);
        CTC_BIT_UNSET(field_val, 8);
        CTC_BIT_UNSET(field_val, 9);
        CTC_BIT_UNSET(field_val, 10);
        CTC_BIT_UNSET(field_val, 11);
        if (loop == 0)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000003*/
            CTC_BIT_SET(field_val, 9);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }
        if (loop == 1)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000203 0x00000003*/
            CTC_BIT_SET(field_val, 8);
            CTC_BIT_SET(field_val, 9);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }
        if (loop == 2)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            CTC_BIT_SET(field_val, 8);
            CTC_BIT_SET(field_val, 9);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }

        if (loop == 3)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            CTC_BIT_SET(field_val, 10);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }

        if (loop == 4)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            CTC_BIT_SET(field_val, 10);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }

        if (loop == 5)
        {
            /*set RTHM_MODE=1,RSAMPLE_DONE_INTEN=1,RDUMMY_THMRD=1,RV_SAMPLE_EN=1*/
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000303 0x00000003*/
            CTC_BIT_SET(field_val, 8);
            CTC_BIT_SET(field_val, 9);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }
        /*mask_write tbl-reg OmcMem 0x8 offset 0x0 0x00000004 0x00000004*/
        index = 0x8;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = GetOmcMemTL(V, data_f, &ds);
        CTC_BIT_SET(field_val, 2);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));

        /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001*/
        index = 0x12;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = GetOmcMemTL(V, data_f, &ds);
        CTC_BIT_SET(field_val, 0);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        if (CTC_CHIP_SENSOR_TEMP == p_value->type)
        {
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000001 0x00000001*/
            index = 0x10;
            cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
            field_val = GetOmcMemTL(V, data_f, &ds);
            CTC_BIT_SET(field_val, 0);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }
        else
        {
            /*mask_write tbl-reg OmcMem 0x10 offset 0x0 0x00000000 0x00000001*/
            index = 0x10;
            cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
            field_val = GetOmcMemTL(V, data_f, &ds);
            CTC_BIT_UNSET(field_val, 0);
            SetOmcMemTL(V, data_f, &ds,field_val);
            cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        }
        sal_task_sleep(10);

        /*mask_write tbl-reg OmcMem 0x12 offset 0x0 0x00000001 0x00000001*/
        index = 0x12;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = GetOmcMemTL(V, data_f, &ds);
        CTC_BIT_SET(field_val, 0);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));

        /*Wait((mask_read tbl-reg OmcMem 0xa offset 0x0 0x00000004) =1)*/
        index = 0xa;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        timeout = SYS_TSINGMA_SENSOR_TIMEOUT;
        while(timeout)
        {
            timeout--;
            CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
            field_val = GetOmcMemTL(V, data_f, &ds);
            if (CTC_IS_BIT_SET(field_val, 2))
            {
                break;
            }
            sal_task_sleep(1);
        }
        if (0 == timeout)
        {
            return CTC_E_HW_TIME_OUT;
        }

        /*mask_write tbl-reg OmcMem 0x11 offset 0x0 0x00000006 0x00000006*/
        index = 0x11;
        cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
        field_val = GetOmcMemTL(V, data_f, &ds);
        CTC_BIT_SET(field_val, 1);
        CTC_BIT_SET(field_val, 2);
        SetOmcMemTL(V, data_f, &ds,field_val);
        cmd = DRV_IOW(sensor[loop], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));
        sal_task_sleep(10);

        if (CTC_CHIP_SENSOR_TEMP == p_value->type)
        {
            /*read-reg OmcMem 0xd offset 0x0*/
            index = 0xd;
            cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
            field_val = GetOmcMemTL(V, data_f, &ds);
            CTC_ERROR_RETURN(_sys_tmm_peri_get_temp_with_code(lchip, field_val, (p_value->value + loop)));
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "temp code %d\n", field_val);
        }
        else
        {
            /*read-reg OmcMem 0xc offset 0x0*/
            index = 0xc;
            cmd = DRV_IOR(sensor[loop],DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip,index, cmd, &ds));
            field_val = GetOmcMemTL(V, data_f, &ds);
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "voltage code %d\n", field_val);
            p_value->value[loop] =  (field_val*1000)/1024;
        }
    }
    return CTC_E_NONE;
}


int32
sys_tsingma_peri_phy_link_change_isr(uint8 lchip, uint32 intr, void* p_data)
{
    CTC_INTERRUPT_EVENT_FUNC event_cb;
    uint32 cmd;
    uint32 cmd_w = 0;
    uint32 table_id;
    uint32 phy_enable[SYS_TSINGMA_PHY_BMP_CNT] = {0};
    uint32 phy_enable1[SYS_TSINGMA_PHY_BMP_CNT] = {0};
    uint8  loop = 0;
    uint8  gchip_id = 0;
    uint8  phy_addr = 0;
    uint8  bus = 0;
    uint8  mdio_ctlr_id = 0;
    uint32 value_a = 0;
    int32 ret = 0;
    uint16 mdio_phy_num = 64;
    uint8 dp_id = 0;
    uint32 mac_id = 0;
    uint16 tbl_idx = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    ctc_port_phy_status_t   phy_link_status;
    sys_intr_type_t    intr_type;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_PHY_STATUS_CHANGE, &event_cb));
    switch(intr)
    {
        case SYS_INTR_FUNC_MDIO_XG_CHANGE_0:
            table_id = MdioLinkChange1_t;
            mdio_ctlr_id = DRV_FROM_TMM(lchip)?2:1;
            dp_id = 0;
            break;
        case SYS_INTR_FUNC_MDIO_XG_CHANGE_1:
            table_id = MdioLinkChange0_t;
            mdio_ctlr_id = 0;
            dp_id = 0;
            break;
        case SYS_INTR_FUNC_DP1_MDIO_XG_CHANGE_0:
            table_id = MdioLinkChange1_t;
            mdio_ctlr_id = 3;
            dp_id = 1;
            break;
        case SYS_INTR_FUNC_DP1_MDIO_XG_CHANGE_1:
            table_id = MdioLinkChange0_t;
            mdio_ctlr_id = 1;
            dp_id = 1;
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    /*read which mac use phy*/
    cmd = DRV_IOR(MdioUserPhy_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), phy_enable);

    if (DRV_FROM_TMM(lchip))
    {
        cmd = DRV_IOR(MdioUserPhy_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 1, DRV_CMD_PP_EN(cmd), phy_enable1);
    }

    sal_memset(&intr_type, 0, sizeof(intr_type));
    intr_type.intr = intr;
    intr_type.sub_intr = INVG;
    intr_type.low_intr = INVG;
    CTC_ERROR_RETURN(sys_usw_interrupt_set_en(lchip, &intr_type, 0));

    cmd = DRV_IOR(table_id, MdioLinkChange0_changeStatus_f);
    cmd_w = DRV_IOW(table_id, MdioLinkChange0_changeStatus_f);
    sal_memset(&phy_link_status, 0, sizeof(phy_link_status));

    for(loop=0; loop < mdio_phy_num; loop++)
    {
        tbl_idx = DRV_FROM_AT(lchip) ? (loop + dp_id*mdio_phy_num) : DRV_INS(dp_id,loop);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd), &value_a), ret, end_proc);
        if(!value_a)
        {
            continue;
        }

        if (loop >= SYS_TSINGMA_MAX_PHY_NUM_PER_BUS)
        {
            bus = mdio_ctlr_id*2 + 1;
            phy_addr = loop - SYS_TSINGMA_MAX_PHY_NUM_PER_BUS;
        }
        else
        {
            bus = mdio_ctlr_id*2;
            phy_addr = loop;
        }

        /*clear status*/
        value_a = 0;
        DRV_FIELD_IOCTL(lchip, tbl_idx, DRV_CMD_PP_EN(cmd_w), &value_a);
        CTC_ERROR_GOTO(sys_usw_peri_get_gport_by_mdio_para(lchip, bus, phy_addr, &dmps_port_info.gport), ret, end_proc);
        CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_MAC_ID, &mac_id), ret, end_proc);
        CTC_MAX_VALUE_CHECK(mac_id, SYS_CPU_MAC_ID_MAX);
        if (mac_id >= SYS_CPU_MAC_ID_MIN && mac_id <= SYS_CPU_MAC_ID_MAX)
        {
            mac_id = mac_id - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP) - (dp_id? MCHIP_CAP(SYS_CAP_CPUMAC_NUM_PER_DP) : 0);
        }
        else if (mac_id >= MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP))
        {
            mac_id = mac_id - MCHIP_CAP(SYS_CAP_MAC_NUM_PER_DP);
        }
        if ((CTC_BMP_ISSET(phy_enable, mac_id) && !dp_id) ||
            (CTC_BMP_ISSET(phy_enable1, mac_id) && dp_id))
        {
            phy_link_status.gport = dmps_port_info.gport;
            phy_link_status.bus = bus;
            phy_link_status.phy_addr = phy_addr;
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "gport 0x%x, mdio bus %d, phy address: 0x%x\n",
                                                   phy_link_status.gport,phy_link_status.bus, phy_link_status.phy_addr);
            if(event_cb)
            {
                event_cb(gchip_id, &phy_link_status);
            }
        }
    }
end_proc:
    sys_usw_interrupt_set_en(lchip, &intr_type, 1);
    return ret;
}

